少しコーディングなまったかなとCrash of Codeでトレーニング
その時使った技を紹介します。
1)join
input()
w=int(input())
c=int((w-1)/2)
s=[i+".0" for i in input().split()]
if c==0:print(" ".join(s))
else:print(" ".join(s[c:-c]))
所見の印象はなんだこれは!
なんとも独特な表現、慣れるしかない。
CSV作成に使えそう
2)コメント
a = int(input())
#print (4032/64)
print(a*(a-1))
特にこの言語は# 範囲していなら”””で囲む。
技というほどのものではないけど、作ったプログラムがこれだけなので...
3)配列
a=[int(i**3)for i in range(2,999)]
n=int(input())
c=0
for i in range(1,int(n**0.33)):
if int(n-i**3) in a:c+=1
print(c)
2から998までの数字の3乗がaという配列に入る。
nという数字が洗えられた時それが2つの整数の3乗の和になっている数を数えるという謎問題を解いている。
ちなみに配列の追加でappendはまず使わない。ここでは使っている箇所がないけど+=がわりと万能
4)ソート
n = int(input())
w=[]
for i in range(n):
f,c = input().split()
w+=[f*int(c)]
l = [i for i in input()]
l.sort()
l="".join(l)
c=0
for i in w:
while 1:
n=l.find(i)
if n==-1:break
c+=1
l=l[:n]+l[n+len(i):]
print(c)
よく使う。最近は配列にタプルを(優先順位とかスコア、項目)なんて入れて
sortで最優先を先頭か後ろを用いたりしている。
文章のなかにaaaとかbbとかがいくつあるかという問題の計算している。
5)enumerate
import sys
n = int(input())
l=[]
a="true"
if n<=1:a="false"
if a=="true":
for i in range(n):
s = input()
if s in l:a="false"
l+=[s]
if a=="true":
for n1,i in enumerate(l[1:]):
c=0
for p in range(len(i)):
print(i[p],l[n1][p],file=sys.stderr)
if i[p]!=l[n1][p]:c+=1
print(c,file=sys.stderr)
if c!=1:
a="false"
#break
print(a)
これは最初見たとき、長い長すぎる、seqぐらいにならんものかと思ったもの
言語製作者もいろいろな思い出とか思う所があるのかもしれない。
enumerate 最初のころは打ち込んだあとエディタの色が変わるとホッとした。
長いが、わざわざ別にカウントアップするなら覚えたほうがマシ(昔は覚えるの面倒だからカウントアップしたほうがマシと思っていた)
つい文章も無駄に長くなってしまった。
プログラムは複数の単語の長さが同じで前の単語と一文字ずつ変わっていればtrueとする問題
6)%な余り
n=int(input())
a=[]
for i in range(1,n+1):
c=0
for j in range(1,i+1):
if i%j==0:c+=1
a+=[(c,i)]
a.sort()
for i in range(5):
if a[-1][0]==a[-2][0]:del a[-1]
print(a[-1][1],a[-1][0])
Codingameをやっているとまあ%を使うことが多い
理由はなぜかわからないが素数好きが多いから。
割られることのない数字に硬い石のような感情がわきあがるのだろうか?
これは逆に割られる数が多いもののなかで最小値を求めるという問題
最後に最小値ということを知って作り直す時間がなかったため、5回ループさせて最小を探しに行く。
5回は適当なよみ。
7)内包表記
import sys
import math
# Auto-generated code below aims at helping you parse
# the standard input according to the problem statement.
a, b = [int(i) for i in input().split()]
# Write an action using print
# To debug: print("Debug messages...", file=sys.stderr)
print(180-a-b)
コメントも全てそのままなのはこれは速攻でとかないといけないため
ちなみに2位の人とは1秒差でした。
[設定内容 ループ (設定されるための条件)]
この記述順がどうにもシックリこなくて最初は、まあ慣れませんでした。
8)** 累乗
n=int(input())
p=int(input())
print(n**p%10)
平方根もmath.sqrtなんて使わなくても**0.5でOK
9)バグ
n = int(input())
p=[]
for i in range(n):
place, x, y = input().split()
x = int(x)
y = int(y)
p+=[(place,x,y)]
px=0
py=0
for i in p:
n,x,y=i
if n=="station":
px=x
py=y
a=[]
a+=["station"]
while int(len(a))<n:
bl=100000000
bn=""
bpx=-1
bpy=-1
for i in p:
n,x,y=i
if n in a:pass
l=(px-x)**2+(py-y)**2
if l<bl:
bl=l
bn=n
bpx=x
bpy=y
px=bpx
py=bpy
a+=[bn]
print(len(a))
print(" ".join(a))
技ではない。時間まで解けなかったバグなぜ配列の長さと数字の比較ができないのか
なやみになやんだ。こういった時、いかにも犯人に見えそうなのを追ってハマる。
犯人は数値を代入していたnに文字列をあとから代入したため。
型指定の不要なpythonならではの技(バグ)
10)ZIP
k=input().lower()
p=len(k)*0.9
for i in range(int(input())):
h=0
for a,b in zip(k,input().lower()):
if a==b:h+=1
o="fail"
if h>=p:o="pass"
print(o)
同じ長さのものがあってそれを逐一比較する時に使える。
これは同じ長さの文章があって片一方がk(key)で
それと90%マッチしたらpassするという。
マークシートの採点にそのまま使えそうなプログラム
11)スライス
m=input().split(" ")
o=""
for n,w in enumerate(m[1:]):
o+=m[0][n]+w+" "
print(o[:-1])
未だにスライスという名前ど忘れする。
この1を口にみたてたニコチャン顔で最後の一文字を外して表示
joinを知る前はこれが唯一の技。
12)in list
c = int(input())
list = input().lower().split()
n = int(input())
for i in range(n):
r = input().split()
o=""
for j in r:
if j.lower() in list:
o+=j[0]+"*"*(len(j)-2)+j[-1]+" "
else:
o+=j+" "
print(o[:-1])
公文書で国民に知らせたくないものにはマスクをかける。そんなプログラム
listに入っている文字は*で真ん中を塗りつぶす。
あと大文字小文字にかかわらずリストにあるものすべて。
13)ループする回数を文字列にする
a="+"*int(input())
for _ in a:print(a)
入力値が5ならこんな表示
+++++
+++++
+++++
+++++
+++++
range(5)より"+"*5の方が短い
コードゴルフでよく使われる技
14)反転
a=0
while 1:
x = int(input())
if x==0:break
t=0
for n,i in enumerate(str(x)[::-1]):
i=int(i)
if n==0:t=i
else:
if t<i:
t+=i
else:
t=0
break
if t>0 and a<x:
a=x
if a==0:a="NONE"
print(a)
プログラムとある数字の最大を答えるというもの
951 5>1 9>5+1 OK
861 6>5 8>6+1(ではない)NG
上の桁の数字が下の桁の個々の数字の合計より大きいというのが条件
951を反転させるために[::-1]としている。
意味はスライスの先頭デフォルトの位置からからスライスの終わりデフォルトの位置、-1の間隔で
-1をしていた場合の先頭位置は終端になるらしい。
[::-1]
しばらくの間、反転させるブラックボックスとして使ってました。
15)入れ替え
a = int(input())
b = int(input())
l=(a**2+b**2)**0.5
if a>b:a,b=b,a
l2=(b**2-a**2)**0.5
if int(l)==l:print(int(l))
elif int(l2)==l2:print(int(l2))
else:print("IMPOSSIBLE")
a,bの整数の辺の長さで最後の一辺も整数の直角三角形が作れるか判断する。
16)最初はランダム
import random
sw =[1 for i in range(int(input()))]
m = int(input())
p=[]
for i in range(m):
a, b = [int(j) for j in input().split()]
p+=[(a,b)]
#p+=[(b,a)]
sp=0
c=0
if m==0:
print("True")
else:
while 1:
c+=1
sw[sp]=0
r=random.randint(0,m-1)
p1,p2=p[r]
if p1==sp:
sp=p2
elif p2==sp:
sp=p1
else:continue
if sum(sw)==0:
print("True")
break
if c>10000:
print("False")
break
思考ルーチンを作る時、まずはランダムで正しく動けるように作る。
このプログラムはノード数とそのノードのリンクを情報に
全てのノードに移動できるかを判断する。
最適化は15分では時間的に厳しいのでランダムパワーで押し切りました。
久しぶりに数時間20数問解いてみて、問題が解けて技を使っているかなというものを選んでみました。