# RogerBW's Blog

 Perl Weekly Challenge 120: Swap Clock 07 July 2021 I’ve been doing the Perl Weekly Challenges. The latest involved more binary manipulation and analogue clocks. (Note that this is open until 11 July 2021.) TASK #1 › Swap Odd/Even bits You are given a positive integer `\$N` less than or equal to 255. Write a script to swap the odd positioned bit with even positioned bit and print the decimal equivalent of the new binary representation. As with last week, one could do this by converting to a binary string, but we already have bitwise operators so we might as well use them. (If there were no limit on the input size it might be a bit more fiddly.) `````` return ((\$n & 0x55)<<1) | ((\$n & 0xAA)>>1); `````` which looks basically the same in the other four usual languages, except Raku where there are "+" signs at the start of the bitwise operators. But because I like the mental gymnastics, I decided to do this one in PostScript as well. You can specify numbers in arbitrary bases, which makes life easier, and this is basically the same algorithm as above. ``````/seob { `````` Make a copy of the input. `````` dup `````` Bitwise-and it with the lower mask, and shift up the result. `````` 16#55 and 1 bitshift `````` Swap that on the stack with the other copy of the input. `````` exch `````` Upper mask and shift down the other copy. `````` 16#AA and -1 bitshift `````` And combine them. `````` or } def `````` And then I wrote a basic test harness, because why wouldn't I? That runs the tests and spits out a table with input, output, and pass/fail status. It can also be conveniently invoked, at least where GhostScript is available, with `ps2txt`, which runs the PostScript code, converts the page image to plain text, and dumps it to standard output: ``````\$ ps2txt ch-1.ps 1. 101 154 Pass 2. 18 33 Pass \$ `````` (I've written PostScript code before now to send stuff explicitly to `stdout`, but that's not what PostScript wants to do in more than a very basic way and it makes it appropriately fiddly.) TASK #2 › Clock Angle You are given time `\$T` in the format `hh:mm`. Write a script to find the smaller angle formed by the hands of an analog clock at a given time. Which seems again as though it has a fairly straightforward solution: determine the angle of each hand, then reduce the difference. Raku: ``````sub ca(\$n) { my \$a=0; `````` Extract hour and minute: `````` if (\$n ~~ /(<[0..9]>+)\:(<[0..9]>+)/) { `````` Convert each one to an angle (note that each minute puts half a degree on the hour hand, so we're in floating point territory): `````` my (\$ha,\$ma)=map {\$_ % 360}, (\$0*30+\$1/2,\$1*6); `````` Take the absolute difference: `````` \$a=abs(\$ha-\$ma); `````` Reduce until we get an angle lying in (-180..180): `````` while (\$a > 180) { \$a-=360; } `````` And take the absolute again. `````` \$a=abs(\$a); } return \$a; } `````` And it's basically the same algorithm in PostScript, though it looks quite different and I don't have regexps: ``````/ca { `````` Split the input string `````` (:) search `````` We now have, for the first test case, `(10) (:) (03) true`. Throw away the `true` (I don't care about error handling here). `````` pop `````` Get the hour angle (hour component only) and roll it to the bottom of the working stack. Throw away the `(:)`. `````` cvi 30 mul 3 1 roll pop `````` We now have `90 (10)`. Make that an integer, copy it, and get the minute angle. `````` cvi dup 6 mul `````` We now have `90 10 60`. Stow that minute angle at the bottom. `````` 3 1 roll `````` We now have `60 90 10`. Generate the minute component of the hour angle and add it to the hour component we already have. `````` 2 div add `````` We now have `60 95`, minute angle and hour angle. Take the difference and reduce. `````` sub abs { dup 180 gt { 360 sub } { exit } ifelse } loop abs } def `````` It's very refreshing to write in a completely different paradigm from time to time. I still need to make notes on what's where in the stack as I go along, particularly when `roll` gets involved. (I'm not sure I have a feel for what's a "natively PostScript" coding style, but using the stack rather than defining local variables, and doing stuff in the order it shows up on the stack rather than shoving it into the order most convenient for me, seem to be a part of it.) Full code on github. Posted by RogerBW at 04:04pm on 12 July 2021 Part 1 seems most easily done by bitshifting, though there were some interesting approaches using arrays of two-character strings. (Perl can split a string into two-character chunks without needing Raku's `comb`, though it's a bit fiddly.) Some people haven't been reading the blogs to be aware of how `oct()` can also parse a binary string. (Granted, it's not the sort of thing you'd notice if you were guessing function names…) A more straightforward approach to part 2: calculate the minutes since 00:00, multiply by 5.5 degrees per minute, then modulo 360. Here's a PostScript version to do that, just for fun: ``````/ca { (:) search pop cvi 60 mul exch pop exch cvi add 5.5 mul { dup 180 gt { 360 sub } { exit } ifelse } loop abs } def `````` Comments on this post are now closed. If you have particular grounds for adding a late comment, comment on a more recent post quoting the URL of this one. Search 10 per page 20 per page 50 per page 100 per page Archive Tags 1920s 1930s 1940s 1950s 1960s 1970s 1980s 1990s 2000s 2010s 3d printing action advent of code aeronautics aikakirja anecdote animation anime army astronomy audio audio tech aviation base commerce battletech beer boardgaming book of the week bookmonth chain of command children chris chronicle church of no redeeming virtues cold war comedy computing contemporary cornish smuggler cosmic encounter coup covid-19 crime cthulhu eternal cycling dead of winter doctor who documentary drama driving drone ecchi economics espionage essen 2015 essen 2016 essen 2017 essen 2018 essen 2019 essen 2022 existential risk falklands war fandom fanfic fantasy feminism film firefly first world war flash point flight simulation food garmin drive gazebo genesys geocaching geodata gin gkp gurps gurps 101 gus harpoon historical history horror hugo 2014 hugo 2015 hugo 2016 hugo 2017 hugo 2018 hugo 2019 hugo 2020 hugo 2022 hugo-nebula reread in brief avoid instrumented life javascript julian simpson julie enfield kickstarter kotlin learn to play leaving earth linux liquor lovecraftiana lua mecha men with beards mpd museum music mystery naval noir non-fiction one for the brow opera parody paul temple perl perl weekly challenge photography podcast politics postscript powers prediction privacy project woolsack pyracantha python quantum rail raku ranting raspberry pi reading reading boardgames social real life restaurant reviews romance rpg a day rpgs ruby rust science fiction scythe second world war security shipwreck simutrans smartphone south atlantic war squaddies stationery steampunk stuarts suburbia superheroes suspense television the resistance the weekly challenge thirsty meeples thriller tin soldier torg toys trailers travel type 26 type 31 type 45 vietnam war war wargaming weather wives and sweethearts writing about writing x-wing young adult Special All book reviews, All film reviews
Produced by aikakirja v0.1