Forum Replies Created

Page 2 of 2
  • SJT

    Member
    April 4, 2023 at 12:00 am in reply to: Challenge 5 – Crack the Code

     

    dc: .Q.a -1+ “j”$ sqrt %[;3] -[;8] :: / decrypt dc

    371 56 20 251 1091 35 683 683 440

     

    A sequence of unaries is close to an ideal style in q. According to Arthur Whitney, Ken Iverson considered even infix notation as a sequence of unaries, e.g. 2*3+4 as (2*)(3+)4.

    Note how qs apply/index dualism allows us to compose a list in with the unary functions.

    Goes without saying that all the iteration is implicit

  • SJT

    Member
    March 2, 2023 at 12:00 am in reply to: My guitar homework

    Love the train of unaries,  !

    My teacher made something of C# also being D?, so

     

    q)note:{flip(x?`$'y)rotate:x}[`$"`"vs"C`C#|Db`D`D#|Eb`E`F`F#|Gb`G`G#|Ab`A`A#|Bb`B"] 
    q)note 
    "EADGBE" E A D G B E F A#|Bb D#|Eb G#|Ab C F F#|Gb B E A C#|Db F#|Gb G C F A#|Bb D G G#|Ab C#|Db F#|Gb B D#|Eb G#|Ab A D G C E A A#|Bb D#|Eb G#|Ab C#|Db F A#|Bb B E A D F#|Gb B C F A#|Bb D#|Eb G C C#|Db F#|Gb B E G#|Ab C#|Db D G C F A D D#|Eb G#|Ab C#|Db F#|Gb A#|Bb D#|Eb

     

     

  • SJT

    Member
    February 2, 2023 at 12:00 am in reply to: Challenge 1 – Triangle Font

    BaiChens solution uses the Scan form of the Do iterator  rather than the Each iterator ' I used.

    Terse q helps us focus on the core of the algorithm. Lets use BaiChens solution as a practice example.

    We can rewrite to eliminate the local variable. And, all other things being equal, good q style prefers infix syntax to bracket notation.

     

    q)8{first[x+1]#x+1}1 
    1 
    2 2 
    3 3 3 
    4 4 4 4 
    5 5 5 5 5 
    6 6 6 6 6 6 
    7 7 7 7 7 7 7 
    8 8 8 8 8 8 8 8 
    9 9 9 9 9 9 9 9 9

     

    The addition surely only needs doing once?

     

    q)4{first[b]#b:x+1}1 
    1 
    2 2 
    3 3 3 
    4 4 4 4 
    5 5 5 5 5

     

    On each iteration the vector argument lengthens. But we need increment only its first item.

     

    q)4{b#b:1+first x}1 
    1 
    2 2 
    3 3 3 
    4 4 4 4 
    5 5 5 5 5

     

    The pattern N f1 is easily recognisable as: Do f N times, starting with 1.

    Tightening up the algorithm saves CPU, but the Each is faster still.

     

    q)ts:10000 {b:first x+1;b#x+1}[100;1] 
    438 64560 
    q)ts:10000 100{b#b:1+first x}1 
    301 63536 
    q)ts:10000 {x#'x} 1+til 100 
    174 63616

     

    On the next episode of the Array Cast (just recorded on Tuesday), Michael Higginson talks about how the terse and interactive APL and q REPLs encourage him to compare multiple solutions in a way he would rarely have time to do when writing Java.

  • SJT

    Member
    February 2, 2023 at 12:00 am in reply to: Challenge 1 – Triangle Font

    This is my favourite, besides being faster! All the iteration is implicit. Lovely use of where on an int vector to generate all the items in one hit.

    Implicit iterations tend to be faster than iterators.

  • SJT

    Member
    January 2, 2023 at 12:00 am in reply to: Challenge 1 – Triangle Font

    Sure!

    The rest of the expression returns a nested list of integers

     

    q){x#’x}1+til 4

    ,1

    2 2

    3 3 3

    4 4 4 4

     

    Remove those spaces? If your brain has been trained by the one potato, two potato* approach of C-like languages, it immediately sees a double loop to work through the result. The vector programmer sees an opportunity to index. Indexing has atomic iteration; it does all the looping we need.

    * This delightful expression was used by Joel Kaplan on the Array Cast podcast.

     

    q)"0123456789"[{x#'x}1+til 4] 
    ,"1" 
    "22" 
    "333" 
    "4444"

     

    Q syntax encourages us to replace nested argument brackets with Index (or Index At for unaries) so were not scanning code back and forth. And prefix notation is syntactic sugar for Index At, so the @s can disappear.

     

    q)count[distinct[[.Q.a[3 17 14 15 26 3 4 0 3]]]] 
    7 
    q)count@distinct@.Q.a@3 
    17 14 15 26 3 4 0 3 7 
    q)count distinct .Q.a 
    3 17 14 15 26 3 4 0 3 7 
    q) 
    q)"0123456789"{x#'x}1+til 4 
    ,"1" 
    "22" 
    "333" 
    "4444"

     

    Shifting to vector thinking from one potato, two potato takes practice, which is why the Vector Dojo exists. (Its also a lot of fun.)

    The last step is to remove the double quotes q uses to display strings. (And the comma it uses to mark a 1-item vector.)

    Q inherits much of ks design principle: no unnecessary typing. The console, stdout and stderr are simply the longs 0, 1 and 2, which (along with communication handles) have unary function syntax. Plainly put, a string argument to 1 is written to stdout as a side effect.

     

    q)1 “til 6”

    til 61

     

    But the result of 1 is still 1, and that got written to the console too and followed as usual by a newline. Terminating an expression with a semicolon stops its result being displayed at the console, and is the only good use for a terminating semicolon. (Multiline lambdas use them as separators, which is similar. An expression not followed by a semicolon separator becomes the lambdas result.)

     

    q)1 “til 6”; til 6

    q)

     

    OK, we ignored the expression result, but we lost the newline too. No unnecessary typing! Instead of joining a newline to the end of each output string, we use the negative of the system handle, which does it for us.

     

    q)1 “til 6n”; til 6

    q)-1 “til 6”; til 6

    q)-1 “0123456789”{x#’x}1+til 4;

    1 
    22 
    333 
    4444

     

    Of course stdout and stderr both default to the console, so where is 0 in all this? Well 0 does what the console does: give it a string and it returns the result of evaluating it.

     

    q)1+0 “til 6”

    1 2 3 4 5 6

     

     

  • SJT

    Member
    December 3, 2022 at 12:00 am in reply to: Five easy pieces #2: getting around

    Eliminating up and dn is a good move, but that doesnt quite work.

     

    q)rnd:{(`up`dn`nr!(f ceiling;(f:{string(x z*s)%s:10 xexp y})floor;.Q.f'))[z][;y;x]} 
    q)q:9.638554216867471 
    q)rnd[q;2;`up] 
    {string(x z*s)%s:10 xexp y}[-_-:][;2;9.638554]

     

  • SJT

    Member
    October 3, 2022 at 12:00 am in reply to: Five easy pieces #2: getting around

    Does the job! Note the use of a dictionary where another language would need a control structure.

    The each can be dispensed with. Both up and dn take vector arguments. .Q.f does not, so d[2] could be .Q.f'[nd;]:

     

    q)rnd:{[x;nd;m] d:`up`dn`nr!(up[;nd];dn[;nd];.Q.f'[nd;]); (d m) x} 
    q)rnd[q+0 1 2;3;`up] 
    "9.639" "10.639" "11.639" 
    q)rnd[q+0 1 2;3;`nr] 
    "9.639" "10.639" "11.639"

     

    Now: can we eliminate repetition? The up and dn functions differ by only a single keyword. And without delegating one of the modes to .Q.f?

    (Hint: a single expression rnd is possible, ?80 characters.)

  • SJT

    Member
    August 3, 2022 at 12:00 am in reply to: Five easy pieces

    I speculate its because its the international standard for dates so Prepare Text uses it.

    At any rate I should note in the Reference that it does so.

  • SJT

    Member
    July 3, 2022 at 12:00 am in reply to: Five easy pieces

    Ingenious use of Prepare Text!

    Maybe a simpler version of it would be "T"sv string"dt"$.z.p.

  • SJT

    Member
    March 3, 2022 at 12:00 am in reply to: Five easy pieces

    Nice! Though I always wonder about using powerful ssr to replace just one character with another.

     

    q)?[;”-“;] . reverse 1(“.”=) string `date$.z.p “2022-03-03”

     

    (The Zen monks wanted to play.)

  • SJT

    Member
    March 3, 2022 at 12:00 am in reply to: Five easy pieces

    Elegant! But is the datetime type not deprecated?

  • SJT

    Member
    March 3, 2022 at 12:00 am in reply to: Five easy pieces

    Too easy? Too unnecessary?  Lets kick it up.

    q)ts: .z.d+.z.t 
    q).h.iso8601 ts 
    "2022-03-02T09:12:34.684000000" 
    q).dt.fmtd[;ts] each `iso`dmy`mdy 
    "2022-03-02" "2/3/2022" "3/2/2022"

    Write .dt.fmtd without control words: no if, do, while or Cond.

  • SJT

    Member
    February 3, 2022 at 12:00 am in reply to: Five easy pieces

    Doesnt get easier than that!

    But the challenge is to code it in q.

  • SJT

    Member
    December 18, 2021 at 12:00 am in reply to: Website with practice examples

    Practice is exactly the right idea! You might find Q by Puzzles helpful some simple puzzles with q solutions that illustrate distinctive features of the language.

    The Reading Room also has puzzles for practice. You might start with John Earnests collection Cats Cradle and then see how the well-known Fizzbuzz game can be written in q.

    Beyond that the Phrasebook is a collection of expressions to do this and that. Well worth studying and maybe you can provide some improvements!

    The problems in this years Advent of Code competition are particularly ripe for vector solutions. I have discussed q solutions to the first weeks problems in the Advent of Code group here. In the new year Ill host a regular online vector d?j? for improving q skills.

     

    Stephen

Page 2 of 2