py 小社賽題解

:partying_face:

Lecturer: 怪怪發明家、瘋狂科學家、三洲地區的松鼠

頒獎

第一筆submit

最後一筆submit

好長的比賽

2022最後一筆submit

2023第一筆submit

跨年局限定

1st place: Whois777

2nd place: willyyoung

3rd place: jjooyy1872

pA 打招呼機器人 坐花

結果怪怪發明大會的冠軍是短尾矮袋鼠的 discord bot = =

簽到題 :partying_face:

基本輸入輸出問題 + 一點點迴圈

Q:

輸入在同一行 S1 S2 ......

並輸出:

Aloha, S1

Aloha, S2

......

有點陷阱的簽到題

怎麼處理同一行的輸入?

input().split()!

把一整行字串以特定符號切割成一個一個值存進一個串列

input().split()

name = input().split()

跑過一整個串列的值來輸出

for i in name:
  # 想做的事
  # i 代表串列 name 裡面依序跑到的值

官解

name = input().split()
for i in name:
    print(f"Aloha, {i}!")

pB 建北電資出任務

不明外星間歇構性威脅能量防禦秘密組織之

半球短波子力場分析暨料維護部門

字母偏移量 -> ascii code!

python 的 ascii code 與字元間的轉換:

print(ord('a')) # 97
print(chr(97)) # a
  • 字元 -> ascii:ord()
  • ascii -> 字元:chr()

想法:

宣告一個空字串 ans

依序轉換原字串每一個字元

再新增到 ans

ans = ''
for i in N:
  i = (ord(i) + int(S) - 97) % 26 + 97
  ans += i # 把轉換好的 i 接到 ans 後面

還記得 EOF 怎麼寫嗎?

while True:
  try:
    # 想做的事
  except EOFError:
    break

官解

while True:
    try:
        N,S,K= input().split()
        ans = ''
        for i in N:
            i = (ord(i)+int(S)-97)%26+97
            ans += chr(i)
        num = ans.count(K)
        print(ans[num-1],end='')
    except EOFError:
        break

pC 跑了很久很久的喜歡分解質因數的松鼠

其實這間堅果專賣店叫 208 的原因是因為這條路叫 St. 208 

喔還有 顯示不出來的那一句是

\(\text{Sir, I must pee.}\)

會不會判斷有多少個不同質因數ㄋ

比較基礎的一種寫法

number = int(input())
i = 2
l = set()
while i<=number and number!=1:
  if number % i == 0:
    number /= i
    l.add(i)
  else :
    i += 1

print(len(l))

如果不會的話 我也只能說其實很正常

想法:

從 2 開始試每一個數字

跑到 300,000 為止

寫一個 allow(number, distinct_prime_factor) 函式

判斷那一個數字的不同質因數數量是否正確!

用變數 times 紀錄出現連續幾個符合條件的數字

當 times 為所要求的 N 個連續數字時 就能輸出ㄌ

如果試到的數字 > 300,000 就輸出 fail 並 break

官解

def allownumber(number, M):
    #看現在這個數字有沒有符合M種不同的質因數
    i=2
    l=set() #存裡面有幾種不同的質因數
    while i<=number**0.5:
        if number%i ==0:
            number = number/i
            l.add(i)
            i-=1
        i+=1
    l.add(number)
    return (len(l))==M

N, M = map(int,input().split())
j=2
times=0
while True:
    while allownumber(j,M) and not times==N:
        times +=1
        if times==N:
            break
        else:
            j+=1
    if times==N:
        for k in range(N):
            print(j-N+1)
            j+=1
        break
    else:
        times=0
    j+=1
    if j>=300000:
        print("fail")
        break

有很多雜瑣的地方

題目的原 source

可以偷撈個 solved

pD 到底是星期幾...

喔喔如果你很好奇的話

今天是星期二喔 :smile:

輸入來源是 dates.txt

要使用檔案處理的方式!

f.open('dates.txt', 'r')
for i in f.readlines(): # 逐行讀取輸入
  # 要做的事
f.close() 

其實很簡單,只需要判斷

今天星期幾

閏年與否

每個月幾天

......
就好了 !!!

好麻煩...😵‍💫

其實你有更好的選擇 --- datetime 模組!

解法?

解法? -- 善用函式

import datetime 
#匯入datetime模組
#BTW,今天星期二
print(datetime.today().weekday())
#1 
#從0開始,星期一回傳0
print(datetime.today().weekday())
#2 
#從1開始,星期一回傳1

官解

import datetime
#匯入 datetime
def correctdate(year, month, day):
    try: 
        datetime.date(year, month, day) 
        #利用datetime.date()函式特性
        #若日期不合法會出現錯誤
    except:
        return False
    else:
        return True

f = open('dates.txt', 'r') #開啟檔案
ans =0
for i in f.readlines(): #逐行讀取檔案
    y, m, d = map(int, i.split()) #統一轉型別
    if(correctdate(y, m, d)): 
        ans+=datetime.date(y, m, d).isoweekday()
        #回傳今天星期幾,並把回傳值加進變數
print(ans)
f.close() #記得關檔案!!!

pE 奧賽羅下棋

題敘肯定是 times1-chang 幻想已久的場景

要從棋譜得知棋局結果

必定得將棋局一步一步地模擬一遍

因此需要儲存棋盤狀態

並在每一步進行翻棋

目標

翻棋

八個方向都要檢查一遍

翻棋

一步一步往前

異色:繼續

同色:成功

空格:失敗

翻棋

一步一步往前

異色:繼續

同色:成功

空格:失敗

用「是否翻棋」決定棋步合法與否

官解

寫的不是很好

有很多重複的地方

class Othello:
    def __init__(self, m, n):
        self.rows = m
        self.cols = n
        self.board = []
        for _ in range(m):
            t = []
            for _ in range(n):
                t.append(0);
            self.board.append(t)
        self.symbols = ['-', 'X', 'O']
        self.turn = 1
        self.n_move = 0

    def sum(self):
        board_sum = 0
        for i in range(self.rows):
            for j in range(self.cols):
                board_sum += self.board[i][j]
        return board_sum

    def flip_x(self, xa, xb, y):
        for x in range(xa+1, xb):
            self.board[y][x] = -self.board[y][x]

    def flip_y(self, ya, yb, x):
        for y in range(ya+1, yb):
            self.board[y][x] = -self.board[y][x]

    def check_topleft(self, x, y, flip=False):
        bias = 1
        while x-bias >= 0 and y-bias >= 0:
            xx = x-bias
            yy = y-bias
            if self.board[yy][xx] == 0:
                return
            if self.board[yy][xx] == self.turn:
                if not flip:
                    self.check_topleft(x, y, True)
                return
            if flip:
                self.board[yy][xx] = self.turn
            bias += 1

    def check_bottomright(self, x, y, flip=False):
        bias = 1
        while x+bias < self.cols and y+bias < self.rows:
            xx = x+bias
            yy = y+bias
            if self.board[yy][xx] == 0:
                return
            if self.board[yy][xx] == self.turn:
                if not flip:
                    self.check_bottomright(x, y, True)
                return
            if flip:
                self.board[yy][xx] = self.turn
            bias += 1

    def check_topright(self, x, y, flip=False):
        bias = 1
        while x+bias < self.cols and y-bias >= 0:
            xx = x+bias
            yy = y-bias
            if self.board[yy][xx] == 0:
                return
            if self.board[yy][xx] == self.turn:
                if not flip:
                    self.check_topright(x, y, True)
                return
            if flip:
                self.board[yy][xx] = self.turn
            bias += 1

    def check_bottomleft(self, x, y, flip=False):
        bias = 1
        while x-bias >= 0 and y+bias < self.rows:
            xx = x-bias
            yy = y+bias
            if self.board[yy][xx] == 0:
                return
            if self.board[yy][xx] == self.turn:
                if not flip:
                    self.check_bottomleft(x, y, True)
                return
            if flip:
                self.board[yy][xx] = self.turn
            bias += 1

    def flipcheck(self, x, y):
        if self.n_move < 4:
            return True
        if self.board[y][x] != 0:
            return False
        old_sum = self.sum()
        # Check left
        for i in range(x-1, -1, -1):
            if self.board[y][i] == 0:
                break
            if self.board[y][i] == self.turn:
                self.flip_x(i, x, y)
                break
        # Check right
        for i in range(x+1, self.cols):
            if self.board[y][i] == 0:
                break
            if self.board[y][i] == self.turn:
                self.flip_x(x, i, y)
                break
        # Check up
        for i in range(y-1, -1, -1):
            if self.board[i][x] == 0:
                break
            if self.board[i][x] == self.turn:
                self.flip_y(i, y, x)
                break
        # Check down
        for i in range(y+1, self.rows):
            if self.board[i][x] == 0:
                break
            if self.board[i][x] == self.turn:
                self.flip_y(y, i, x)
                break
        self.check_topleft(x, y)
        self.check_bottomright(x, y)
        self.check_topright(x, y)
        self.check_bottomleft(x, y)
        # Check if anything is flipped
        if self.sum() == old_sum:
            return False
        return True

    def move(self, x, y):
        if not self.flipcheck(x, y):
            return False
        self.board[y][x] = self.turn
        self.turn = -self.turn
        self.n_move += 1
        return True

    def print(self):
        for i in range(self.rows):
            for j in range(self.cols):
                print(self.symbols[self.board[i][j]], end=' ')
            print()
        print()

if __name__ == '__main__':
    m, n = map(int, input().split())
    a = Othello(m, n)
    ill = False
    while a.n_move < a.rows * a.cols:
        move = input()
        x = ord(move[0]) - ord('a')
        y = int(move[1:]) - 1
        if not a.move(x, y):
            print('illegal')
            print(move)
            ill = True
            break
        a.print()
    if not ill:
        s = a.sum()
        if s > 0:
            print('black')
        elif s < 0:
            print('white')
        else:
            print('draw')