[ネタバレ注意] paiza_POH7_swiftオープンの解答例 70byte

  • 1
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

背景

paizaのオンラインハッカソン(POH)の7回目で、特定の問題においてswiftでコードゴルフする問題が出題されていた。
問題は下記サイトにログインして、メガネの問題を参照。
ランキングを見るだけなら、ログインしなくても下記で確認できる。

https://paiza.jp/poh/ando

Swiftオープン トップ50
「めがね」ゲットチャレンジの最速タイムラインキングです。

最初は真っ当に解いて206byteを提出したものの、途中から極端に短い解答がでてきたので、自分も考えてみた。
答えを公開してもよいらしいので、自分の解答例をここに公開する。

解答例

下記解答で70byte。

let n=[598,846,2651,128,667][Int(readLine()!)!%29/6]
print(n/52,n%52)

解答例までの過程

この解答例は、与えられる入力とその出力を事前に知っている必要がある。
今回は以下のとおり。これらは毎回固定なので、二分探索で地道に解答を探した。

Q1: n =  36, m = 5, i = 16, j = 14
Q2: n =  52, m = 5, i =  2, j = 24
Q3: n =  34, m = 7, i = 11, j = 26
Q4: n =  54, m = 6, i = 12, j = 43
Q5: n = 100, m = 6, i = 50, j = 51

最初はDictionaryで答えに対応するものを直書き。
最初の入力で値がかぶるものはないので、その値をkeyにしてvalueに答えを埋め込む形。

print([36:"16 14",52:"2 24",34:"11 26",54:"12 43"][Int(readLine()!)!] ?? "50 51")

上記は素直な解答ではあるものの、ちょっとkeyがじゃまに感じる。
これを解消すべく、次はArrayで表現する方法を考える。

[f(36),f(52),f(34),f(54),f(100)].sort == [0,1,2,3,4]
となるfを考える。もし存在すれば、答えを並べた配列が使える。
99までの値で適当に四則演算を試したところ、f(x) = x % 29 / 6が該当した。

[1] pry(main)> [36,52,34,54,100].map{|n| n%29/6}
=> [1, 3, 0, 4, 2]

あとは上記の番号の順番に答えを用意し、選択する。
一時期71byteで拮抗していた時は、これと同じ回答の人がいた予感がする。

print(["11 26","16 14","50 51","2 24","12 43"][Int(readLine()!)!%29/6])

71byteで満足していたものの、上回る解答が出てきたのでもう少し考えてみた。
文字列が長く感じたので、二組の数値を一つに変換してみることに。
答えで52以上の数値は無いので、x = n*52+mとすれば、n = x/52, m = x%52と展開できる。
そうすると以下の様な数値が出てくるので、これを入れる。

let n=[598,846,2651,128,667][Int(readLine()!)!%29/6]
print(n/52,n%52)

これで70byte。ここで燃え尽きたので54byteと182byteの解答が知りたい。

おまけ 70byte別解

_={print(202056715>>$0&63,727921562>>$0&63)}(Int(readLine()!)!%29/6*6)
_={print($0/52,$0%52)}([598,846,2651,128,667][Int(readLine()!)!%29/6])