USING: accessors kernel math ; IN: project-euler.215 TUPLE: block two three ; TUPLE: end { ways integer } ; : ( l r -- t ) block boa ; inline : ( n -- t ) end boa ; inline : end new ; inline : 1 ; inline : failure? ( t -- ? ) ways>> zero? ; inline : add-ends ( t t -- t ) [ ways>> ] bi@ + ; inline : choice ( t p q -- t t ) [ [ two>> ] [ three>> ] bi ] 2dip bi* ; inline : merge ( t t -- t ) over block? over block? [ [ [ [ two>> ] bi@ merge ] [ [ three>> ] bi@ merge ] 2bi ] [ nip ] if ] [ [ drop ] [ add-ends ] if ] if ; GENERIC: h-1 ( t -- t ) GENERIC: h0 ( t -- t ) GENERIC: h1 ( t -- t ) GENERIC: h2 ( t -- t ) M: block h-1 [ h1 ] [ h2 ] choice merge ; M: block h0 drop ; M: block h1 [ [ h1 ] [ h2 ] choice merge ] [ [ h0 ] [ h1 ] choice merge ] bi ; M: block h2 [ h1 ] [ h2 ] choice merge swap ; M: end h-1 drop ; M: end h0 ; M: end h1 drop ; M: end h2 dup failure? [ ] unless ; : next-row [ h-1 ] [ h1 ] choice swap ; : first-row [ ] dip 1- [ over roll ] times 2nip ; GENERIC: total ( t -- n ) M: block total [ total ] dup choice + ; M: end total ways>> ; : solve ( width height -- ways ) [ first-row ] dip 1- [ next-row ] times total ; : euler215 32 10 solve ;