package Ġad vent of code . y 2 0 1 7 Ċ Ċ import Ġad vent of code . Ad vent Solution Ċ import Ġad vent of code . util . collections . take While Distinct Ċ Ċ object ĠDay 1 6 Ġ: ĠAd vent Solution ( 2 0 1 7 , Ġ 1 6 , Ġ" Per mutation ĠProm en ade ") Ġ{ ĊĊ ĉ override Ġfun Ġsolve Part One ( input : ĠString ): ĠString Ġ= Ġd ance ( parse Input ( input ), Ġ" abcdefgh ijkl mn op ") ĊĊĊ ĉ // There 's Ġactually Ġa Ġsmall Ġupper Ġbound Ġfor Ġthe Ġloop Ġsize ! ĠLand au 's ĠFunction Ċ ĉ override Ġfun Ġsolve Part Two ( input : ĠString ): ĠString Ġ{ Ċĉ ĉ val Ġd ance Moves : ĠList < Action > Ġ= Ġparse Input ( input ) Ċĉ ĉ val Ġorder ings Ġ= Ġgenerate Sequence (" abcdefgh ijkl mn op ") Ġ{ Ġd ance ( d ance Moves , Ġit ) Ġ} Ċĉĉĉ ĉ . take While Distinct () Ċĉĉĉ ĉ . toList () ĊĊĉ ĉ val Ġremainder Ġ= Ġ( 1 _ 0 0 0 _ 0 0 0 _ 0 0 0 Ġ% Ġorder ings . size ) ĊĊĉ ĉ return Ġorder ings [ remainder ] Ċ ĉ } ĊĊ ĉ private Ġfun Ġparse Input ( input : ĠString ): ĠList < Action > Ġ= Ġinput . split (",") Ċĉĉ ĉ . map Ġ{ Ġmove Ġ-> Ċĉĉĉ ĉ when Ġ( move [ 0 ]) Ġ{ Ċĉĉĉĉ ĉ 's ' Ġ-> ĠAction . Spin ( move . substring ( 1 ). toInt ()) Ċĉĉĉĉ ĉ ' x ' Ġ-> Ġmove . substring ( 1 ). split ('/ '). let Ġ{ ĠAction . Exchange ( it [ 0 ]. toInt (), Ġit [ 1 ]. toInt ()) Ġ} Ċĉĉĉĉ ĉ ' p ' Ġ-> ĠAction . Prom en ade ( move [ 1 ], Ġmove [ 3 ]) Ċĉĉĉĉ ĉ else Ġ-> Ġthrow ĠIllegalArgumentException ("$ move Ġis Ġnot Ġa Ġd ance Ġmove ") Ċĉĉĉ ĉ } Ċĉĉ ĉ } ĊĊ ĉ private Ġfun Ġd ance ( moves : ĠList < Action >, Ġinitial Positions : ĠString ) Ġ= Ċĉĉ ĉ moves . fold ( initial Positions ) Ġ{ Ġacc , Ġaction Ġ-> Ġaction . execute ( acc ) Ġ} Ċ } Ċ Ċ private Ġsealed Ġclass ĠAction Ġ{ Ċ ĉ abstract Ġfun Ġexecute ( programs : ĠString ): ĠString ĊĊ ĉ class ĠSpin ( private Ġval Ġn : ĠInt ) Ġ: ĠAction () Ġ{ Ċĉ ĉ override Ġfun Ġexecute ( programs : ĠString ) Ġ= Ġprograms . take Last ( n ) Ġ+ Ġprograms . drop Last ( n ) Ċ ĉ } ĊĊ ĉ class ĠExchange ( private Ġval Ġi 1 : ĠInt , Ġprivate Ġval Ġi 2 : ĠInt ) Ġ: ĠAction () Ġ{ Ċĉ ĉ override Ġfun Ġexecute ( programs : ĠString ): ĠString Ġ{ Ċĉĉ ĉ val Ġex changed Ġ= Ġprograms . toCharArray () Ċĉĉ ĉ ex changed [ i 1 ] Ġ= Ġprograms [ i 2 ] Ċĉĉ ĉ ex changed [ i 2 ] Ġ= Ġprograms [ i 1 ] Ċĉĉ ĉ return ĠString ( ex changed ) Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ class ĠProm en ade ( private Ġval Ġp 1 : ĠChar , Ġprivate Ġval Ġp 2 : ĠChar ) Ġ: ĠAction () Ġ{ Ċĉ ĉ override Ġfun Ġexecute ( programs : ĠString ): ĠString Ġ{ Ċĉĉ ĉ val Ġprom en aded Ġ= Ġprograms . toCharArray () Ċĉĉ ĉ val Ġi 1 Ġ= Ġprograms . indexOf ( p 1 ) Ċĉĉ ĉ val Ġi 2 Ġ= Ġprograms . indexOf ( p 2 ) Ċĉĉ ĉ prom en aded [ i 1 ] Ġ= Ġprograms [ i 2 ] Ċĉĉ ĉ prom en aded [ i 2 ] Ġ= Ġprograms [ i 1 ] Ċĉĉ ĉ return ĠString ( prom en aded ) Ċĉ ĉ } Ċ ĉ } Ċ } Ċ