Skip to content

Instantly share code, notes, and snippets.

@flada-auxv
Last active March 24, 2016 11:23
Show Gist options
  • Save flada-auxv/89a1e036fd98a3b41920 to your computer and use it in GitHub Desktop.
Save flada-auxv/89a1e036fd98a3b41920 to your computer and use it in GitHub Desktop.
esm_doukaku
class Player
attr_reader :size
def initialize(senryaku)
@count = 0
@size = senryaku.size
@senryaku = senryaku
@senryaku_enum = senryaku.each_char.cycle
end
def ready!
@count = 0
end
def next_hand
@senryaku_enum.take(@count += 1).last
end
def janken(other_player)
self.ready!
other_player.ready!
count = [self.size, other_player.size].max
loop do
hand = self.next_hand
other_player_hand = other_player.next_hand
if hand == other_player_hand
break(self) if (count -= 1) < 0
next
end
win =
case hand
when 'R'
other_player_hand == 'S' ? self : other_player
when 'P'
other_player_hand == 'R' ? self : other_player
when 'S'
other_player_hand == 'P' ? self : other_player
end
break(win)
end
end
def inspect
"(#{@senryaku.to_s})"
end
end
POWERS_OF_TWO = (1..Float::INFINITY).lazy.map {|i| 2 ** i }
# [R, S, P, R] => [[R, S], [P, R]]
# [R, S, P] => [R, [S, P]]
def combine(tournament)
current_tournament_size = tournament.size
next_tournament_size = POWERS_OF_TWO.take_while {|i| i <= current_tournament_size }.force.last
karikomi = current_tournament_size - next_tournament_size
if karikomi > 0
zako = tournament.last(2 * karikomi).each_slice(2).to_a
tournament[0..-(2 * karikomi + 1)] + zako
else
tournament.each_slice(2).to_a
end
end
def battle(tournament)
if tournament.size == 1
a, b = tournament[0]
return a.janken(b)
end
res = tournament.map {|a, b| a && b ? a.janken(b) : a }
battle(combine(res))
end
def test(str, answer)
tournament = str.scan(/\([RSP]+\)/).map {|str| str.delete!('()') }.map {|str| Player.new(str) }
res = battle(combine(tournament)).inspect
p res == answer
end
test("(PSSRP)(PRP)", "(PRP)")
test("(RSP)(R)(RPS)(SP)", "(RPS)")
test("(RPS)(R)(RSP)(SP)(RSSP)", "(RSSP)")
test("(RRS)(S)(PSSRP)(PRP)(PSS)", "(PRP)")
test("(PRS)(PSPP)(PRSP)(S)(RR)(SSPR)", "(PRS)")
test("(PSRP)(PR)(RPRPR)(PSSPP)(SP)(SRPP)(PR)", "(SP)")
test("(SPS)(R)(RP)(RRS)(PPRRS)(R)(RS)(RRRRP)", "(PPRRS)")
test("(PPSRPSPRR)(SP)(PPPRSSR)(PS)(P)(PRSPS)(PP)(RSSR)", "(SP)")
test("(SRPRS)(SRPSRS)(SPP)(RSPRS)(S)(SRPSPS)(RSPPSSS)(SRRPRRPSSP)", "(RSPPSSS)")
test("(SRSPSPRS)(RRPRRS)(PRRRRS)(RSSPSSRPS)(PPSSPPRR)(PPSPPS)(PSPSPSSSP)(RPPRPS)", "(PRRRRS)")
test("(S)(PRS)(RSRP)(S)(PPRR)(PP)(RSSS)(P)(RSR)", "(PP)")
test("(RPR)(P)(PSPR)(SRSRP)(SR)(RPPR)(RRS)(S)(SSPR)(PRPR)", "(RPPR)")
test("(PSR)(PPPRR)(S)(SP)(S)(PR)(SPSRP)(PPSRR)(PRPPR)(RRRSP)(SR)", "(S)")
test("(PPRPP)(RSS)(PRS)(R)(RPRP)(SPSSS)(RR)(PPRP)(RSSS)(RSRS)(RP)", "(PPRPP)")
test("(P)(PPPRR)(RRRS)(RR)(RPRSS)(PRSPS)(PP)(R)(PSR)(RPPP)(RP)(SSSR)", "(PSR)")
test("(SR)(P)(RRPRP)(RSPS)(PSS)(SPPSP)(RRPS)(PR)(RRRSR)(PRR)(SSS)(RRRSS)(P)", "(SR)")
test("(PS)(RS)(RR)(RPR)(SR)(SP)(PRP)(PPS)(R)(PRSP)(SSPRR)(SP)(PPR)(RSRR)", "(SSPRR)")
test("(RRRRS)(SRPRR)(PPSS)(SSPPS)(R)(R)(P)(P)(PSSPR)(S)(RRPP)(SPRR)(S)(RR)(S)", "(PSSPR)")
test("(RRPSSRP)(SSSSSP)(RRSPSS)(PRSRRSRP)(SSRRRRR)(SS)(SSSSSSPPRP)(R)(SRRSR)(PPPSRSP)(RPRS)(RSRPPRS)(RPPPPRPR)(PRRSR)(RPRRSR)", "(PPPSRSP)")
test("(SSSRS)(SRPSS)(RSPRP)(RPPPP)(S)(PPRPS)(RRR)(PS)(RPSPS)(SPP)(PSRS)(P)(P)(RR)(S)(PSP)", "(RSPRP)")
test("(SPP)(PR)(SR)(SRPSP)(P)(RR)(SSPP)(RS)(RRRPP)(R)(PRSPS)(RRPP)(RRRSS)(RRRSS)(RSP)(SRPR)(PPS)", "(SPP)")
test("(SSS)(SSPR)(SSRR)(P)(PRRSP)(RRRPP)(PR)(P)(PS)(PPR)(R)(SRPSR)(R)(S)(SSPRS)(SRPR)(PPPR)(SRS)", "(SSRR)")
test("(PR)(R)(PRPS)(PR)(S)(PS)(R)(P)(R)(SS)(RP)(SS)(SP)(R)(SPR)(RPR)(PSP)(PPPS)(SPRPR)", "(RP)")
test("(SPS)(SRPR)(P)(SPPS)(SS)(RS)(SRPPS)(SRSPS)(RSR)(SRPR)(P)(SPSS)(SRS)(SP)(RSRRP)(PP)(SR)(RPRP)(P)(SPPPS)", "(RSR)")
test("(SSRSP)(SPRRPRSPS)(SPSPS)(PRPR)(SPPRP)(RS)(SPSSPRRS)(PSPPRPSSP)(PSRRRRRP)(SPPRS)(SRRP)(SP)(SRSPRPSP)(PPSRRRSR)(PPPSSRSR)(PRPSPS)(SRR)(RP)(SP)(RSRPSPSSRS)", "(RS)")
test("(RRPS)(SRPR)(PS)(SPPS)(SS)(RS)(SRPPS)(SRSPS)(RSR)(SRPR)(P)(SPSS)(SRS)(SP)(RSRRP)(PP)(SR)(RPRP)(P)(SPPPS)", "(RRPS)")
test("(S)(PRSRR)(PP)(PSSSS)(SR)(SRRP)(PRRPR)(PRSS)(SPPS)(SS)(SPPR)(SSRSR)(PSRPP)(RSP)(R)(P)(PPP)(SS)(SP)(SSSS)(RRSR)", "(SRRP)")
test("(PS)(R)(R)(S)(S)(SSP)(RPPP)(RPSP)(RPRR)(R)(SRRSS)(RSR)(PS)(PRP)(SSSS)(S)(SSSR)(SS)(PSP)(RS)(PSRSR)(SR)", "(SR)")
test("(RSPSS)(RRSSR)(S)(RRS)(PSSRR)(S)(RPRRP)(RS)(PS)(RR)(R)(PSRR)(RPPRP)(SSS)(S)(R)(R)(SRSS)(PR)(S)(RRPPS)(S)(SSPRR)", "(RRS)")
test("(PSSS)(RRRPR)(PRPP)(RSSS)(RR)(RP)(PPS)(PSR)(SPS)(SRSS)(R)(RR)(SPRSR)(RSPRP)(RRSP)(SSRRP)(RSSSR)(PPSS)(PRS)(RRSRS)(PS)(SS)(P)(SPR)", "(PRPP)")
test("(RSRPSS)(RPPRPRRSP)(PRPSRSRPPP)(SSRSSRS)(RPS)(SP)(PPPPPSSP)(RRRPSR)(PSR)(SRSRSSR)(RPSSSRP)(RRSPSSSPPR)(RS)(SRRRSPRP)(PR)(RSSRPSSS)(PPRRRRRR)(RRSRP)(RRR)(PSPRSSPRP)(PRPPRSSRP)(SPPSPSS)(PSS)(RPS)(P)(RRSRSP)(PS)(RRPSSSRR)(RR)(PPPSPRPR)(PS)(PRSSRPR)(RRP)(PSRPR)(PS)(R)(RRPP)(SSPPSS)(SRPSSS)(RRSRRPRPP)", "(SPPSPSS)")
@flada-auxv
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment