0

Advent of code day 16

 2 years ago
source link: https://dev.to/marcoservetto/advent-of-code-day-16-1a83
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Advent of code day 16

Ok, here it is.
I hate this even more than the Bingo. In particular, the text was very unclear about padding. Padding can basically be ignored in this exercise.

reuse [L42.is/AdamsTowel]
Fs = Load:{reuse[L42.is/FileSystem]}

Decoder = {
  Map = Collection.map(key=S val=I.List)

  class method I.List(S that) = This.map().val(key=that).val()

  L={class method I.List (S that)=\()(
    for c in that.split() \add(I(string=c)))}

  @Cache.Lazy class method Map map()=\[
    key=S"0" val=L(S"0000");
    key=S"1" val=L(S"0001");
    key=S"2" val=L(S"0010");
    key=S"3" val=L(S"0011");
    key=S"4" val=L(S"0100");
    key=S"5" val=L(S"0101");
    key=S"6" val=L(S"0110");
    key=S"7" val=L(S"0111");
    key=S"8" val=L(S"1000");
    key=S"9" val=L(S"1001");
    key=S"A" val=L(S"1010");
    key=S"B" val=L(S"1011");
    key=S"C" val=L(S"1100");
    key=S"D" val=L(S"1101");
    key=S"E" val=L(S"1110");
    key=S"F" val=L(S"1111");
    ]}

Input = Data:{
  mut I.List that
  var I removed = 0I
  mut method I b() = (
    \removed(\removed+1I)
    (left,removeLeft)=\#that
    left
    )
  read method Bool isPadding() = 
    \that.size()<4I ||
    \that.val(0I)+\that.val(1I)+\that.val(2I) ==0I
  }
Packet = Data.AddList:Data:{ List = {}
  I v,I t,Num val,List sub
  }
ParsePacket = {
  class method Packet (mut Input that) = {
    v   = \val(that,bits=3I)
    t   = \val(that,bits=3I)
    if t==4I return \(v=v,t=t,val=this.vals(that),sub=\())
    size = ( if that.b()==0I 15I else 11I )
    psSize = \val(that,bits=size)
    (removed) = that
    if size==11I return \(v=v,t=t,val=Num(psSize),sub=\()(
      for i in Range(psSize) \add(ParsePacket(that))
      ))
    X[that.that().size()>=psSize]
    return \(v=v,t=t,val=Num(psSize),sub=\()(
      while that.removed()-removed<psSize \add(ParsePacket(that))
      ))
    }
  class method I val(mut Input that, I bits) = 0I.acc()(
    for i in Range(bits) \val((\val*2I)+that.b()) 
    )
  class method Num vals(mut Input that) = {
    (b0,b1,b2,b3,b4)= that
    res = Num((b1*8I)+(b2*4I)+(b3*2I)+b4)
    if b0==0I return res
    pre = that.removed()
    rec = \vals(that)
    var seen = that.removed() - pre
    mul = 1Num.acc()(while seen>3I (seen-=5I, \times(16Num)))
    return (res*mul)+rec
    }
  }
Versions={class method I (Packet that) = 
  that.v().acc()(for p in that.sub() \add(This(p)))
  }
Part2 = {class method Num (Packet that) = {
  if that.t()==0I return 0Num.acc()(for p in that.sub() \add(This(p)))
  if that.t()==1I return 1Num.acc()(for p in that.sub() \times(This(p)))
  if that.t()==2I return This(that.sub().left()).acc()(for p in that.sub() \val(\val.min(This(p))))
  if that.t()==3I return 0Num.acc()(for p in that.sub() \val(\val.max(This(p))))
  if that.t()==4I return that.val()
  (left,right) = that.sub()
  if that.t()==5I return if This(left)>This(right) 1Num else 0Num
  if that.t()==6I return if This(left)<This(right) 1Num else 0Num
  if that.t()==7I return if This(left)==This(right) 1Num else 0Num
  error X" unrecognized packet type"
  }}
Main = (
  input = Fs.Real.#$of().read(\"input").trim()
  parsed = Input(\()(for c in input.split() for e in Decoder(c) \add(e)))
  ps = Packet.List()(while !parsed.isPadding() \add(ParsePacket(parsed)))
  Debug(Versions(ps.left()))//993
  Debug(Part2(ps.left())) //144595909277
  )

Enter fullscreen mode

Exit fullscreen mode

Note this funky code :-P

(left,removeLeft) = \#that

Enter fullscreen mode

Exit fullscreen mode

I'm not sure what to think about it. It is a cool way to go next after reading left, but it also feel like an abuse of the 'object decomposition' syntax.. any idea about it?
The more I use that pattern the more it feels ok... but I'm I just getting use to the anti-pattern, or is it actually a good way to express stuff?

Consider this other use of the same idea:

(b0,b1,b2,b3,b4) = that

Enter fullscreen mode

Exit fullscreen mode

Here I extract 5 bits from the input. This is nice and readable, and uses the same pattern of the 'removeLeft' above.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK