2025年10月1日 星期三

7 kyu:Set the Alarms Up 別人簡潔的寫法

 嘗試練習7 kyu: Set the Alarms Up

使用Lua語言,題目是設定連續鬧鐘,如果不是寫成程式,
就數學上,大概只會用到小學數學。

我自己的寫法是:

local function set_the_alarms_up(time, n)
  local t = os.time{year=1970, month=1, day=1, hour=0}
  local hours = string.sub(time, 1, 2)
  local hour = tonumber(hours)
  local ms = string.sub(time, 4, 5)
  local m = tonumber(ms)
  t = t + m*60 + hour*3600
  local a = {os.date("%H:%M", t)}
  for i = 2, n do
    a[i] = os.date("%H:%M", t + 300*(i-1))
  end
  return a
end

return set_the_alarms_up

Note: 

1. os.time設定值,是以秒為單位

2. 在Unix system 0值在00:00:00 UTC, January 1, 1970,但要注意台灣的時區是+08:00

所以台灣的os.time{year=1970, month=1, day=1, hour=0}不是0,而是-28800


看到別人的寫法:

local function set_the_alarms_up(time, n)
  local res, h, m = {}, time:match "^(%d+):(%d+)$"
  for i = 1, n do
    res[i] = os.date("%H:%M", (h * 60 + m + 5 * (i - 1)) * 60)
  end
  return res
end

return set_the_alarms_up

其中local res, h, m = {}, time:match "^(%d+):(%d+)$"

這行我覺得寫得很精簡,

GPT 5解釋如下:

這一行 Lua 寫法:

local res, h, m = {}, time:match "^(%d+):(%d+)$"

可以分成兩部分來看:


1. 左邊變數定義

local res, h, m = ...
  • local:表示這些變數是區域變數 (scope 只在當前程式塊內)

  • res:被初始化為 {},也就是一個新的空 table。

  • h, m:會由右邊 time:match(...) 的結果來賦值。


2. 右邊字串模式匹配

time:match "^(%d+):(%d+)$"

這是 Lua 的 字串方法,等同於:

string.match(time, "^(%d+):(%d+)$")
  • ^:匹配字串開頭

  • %d+:匹配一個或多個數字

  • ::匹配冒號字元本身

  • $:匹配字串結尾

所以這個 pattern 會匹配 「數字:數字」 這種格式,例如 "12:34"。

由於有兩個括號捕獲組 (%d+),string.match 會返回兩個結果:

  • 第一個捕獲 → h

  • 第二個捕獲 → m


3. 綜合起來

如果:

time = "12:34"

那麼執行後:

res = {} -- 空表 h = "12" -- 字串 "12" m = "34" -- 字串 "34"

👉 簡單說:
這行程式碼同時做了兩件事:

  1. 建立一個空表 res

  2. 從字串 time 中解析出「小時」和「分鐘」(字串型態),分別放到 h 和 m 裡。


另外為何time:match "^(%d+):(%d+)$"的函式不用括號?

GPT 5 解釋如下:

這個是 Lua 的語法糖 (syntactic sugar) 👍

在 Lua 裡,如果一個函式呼叫 只有一個參數,而這個參數是:

  • 一個 字串常值

  • 或是一個 table 常值

那麼可以省略小括號 ()。


範例:

print("hello") -- 一般寫法 print "hello" -- 語法糖,省略括號 f({x=1, y=2}) -- 一般寫法 f {x=1, y=2} -- 語法糖,省略括號

套用到你的程式

time:match("^(%d+):(%d+)$") -- 正常呼叫 time:match "^(%d+):(%d+)$" -- 語法糖,省略括號

這兩行 完全一樣,只是簡潔寫法。


👉 所以你看到的 time:match "^(%d+):(%d+)$" 只是 Lua 的簡化呼叫方式,函式其實還是有接到參數的。


2025年9月29日 星期一

Lua中的string s[index]並不像Python是String中的字元

 練習8 kyu的簡單題:

Exclamation marks series #2: Remove all exclamation marks from the end of sentence

題目是把字串最後連續的驚嘆號(!)去掉,但要注意,只去除最後連續的,

如果不在最後連續,不用去掉。

我的寫法一開始是:

local function remove_marks(s)
  local a = ''
  for i = #s, 1, -1 do
    if "!" ~= s[i] then
      a = string.sub(s, 1, i)
      return a
    end
  end
  return a
end

return remove_marks;

注意,這邊Lua跟Python的語法不一樣,

if "!" ~= s[i] then

除了Lua的不等於是~以外,

此時的s[i]是回傳nil,不是回傳s的第i個字元,

所以必需改寫如下:

local function remove_marks(s)
  local a = ''
  for i = #s, 1, -1 do
    ss = string.sub(s, i, i)
    if "!" ~= ss then
      a = string.sub(s, 1, i)
      return a
    end
  end
  return a
end

return remove_marks;

2025年9月24日 星期三

Scribd

主要是研究所時期做的一些投影片,少部份是後來做的:

 https://www.scribd.com/user/21556865/davidsmc

"8 Kyu":Never visit a . . . !?特解

Never visit a . . . !?

 這題我是用暴力解的.但解了之後,看別人其實有特解,
就是直接輸出9-apple
原因在於:

1. Sum all the digits of n.

假設n 是a + 10*b + 100*c + 1000*d
Sum all the digits of n的結果是s.

s=a+b+c+d

2. Subtract the sum from n, and it is your new n.

所以 new n = n - s 

= a + 10*b + 100*c + 1000*d - (a + b + c + d)

= 9*b + 99*c + 999*d

所以一定是9的倍數。
其餘不是千位數的n類推,也是9的倍數

3. If the new n is in the list below return the associated fruit, otherwise return back to task 1.

...

9-apple

...

18-apple

...

27-apple

...

36-apple

...

45-apple

...

54-apple

...

63-apple

...

72-apple

...

81-apple

...

90-apple

91-kiwi

92-banana

93-kiwi

94-banana

95-melon

96-banana

97-melon

98-pineapple

99-apple

100-pineapple

9的倍數,相關的水果一定是apple.不會是別的。 

Swift storyboard for FitAutoTest 雜記

info.plist:

看是Ordinary.storyboard 還是 TabView.storyboard ?

在info.plist:

Main storyboard file base name (macOS): Ordinary
則是Ordinary

==========================================

實際在跑的<project_name>_<station_name>.plist

以branch B495_Pizza為例:

PlistHelper.swift:

func getStationProjectName() -> String {

        return "\(self.getProjectName())_\(self.getStationName())"

}


B44445_QT2Flow.swift:

SAP109_MBFlow.swift:

ConcurrentFlow.swift:

...

let stationProjectName = self._plistHelper!.getStationProjectName()

let testList = TestListFactory.getTestList(stationProjectName: stationProjectName)

...


TestListFactory.swift:

class TestListFactory {

    static func getTestList(stationProjectName: String) -> ITestList? {

        switch stationProjectName {

        case "B444445_QT2":

            return B444445_QT2List()

        ...

        case "B495_Pizza":

            return B495_PizzaList()

        ...

        case "B499_Pizza":

            return B499_PizzaList()

        case "Test_Pizza": // Temp 20250219

            return B495_PizzaList()

        default:

            return nil

        }

    }

}

==========================================

FitAutoTest, 找出程式GUI的start,

Ordinary.storyboard點兩下,

Start Btn0 -> Show the Connections inspector


Referencing Outlets

看到叫做startBtn0


Sent Actions

看到Ordinary Controller

dutStart0


OrdinaryController.swift:

@IBAction func dutStart0(_ sender: Any) {

        super.handleStartBtnClick(dutIndex: 0)

    }


BaseViewController.swift:

...

self.startBtnList = [startBtn0, startBtn1, startBtn2, startBtn3]


func handleStartBtnClick(dutIndex: Int){

    ...

     if self.setUIAfterStart(dutIndex: dutIndex, isAlarm: true) {

            ...

            self.startBtnList[dutIndex].isEnabled = false

            self._testflow!.testStart(startTime: startTime, allDutIndexSnMap: [dutIndex: self.snTextFieldList[dutIndex].stringValue])

            ..

    }

}


ITestFlow.swift:

protocol ITestFlow {

    ...

    func testStart(startTime: Date, allDutIndexSnMap: Dictionary<Int, String>) -> ()

}


B444445_QT2Flow.swift:

class B444445_QT2Flow : ITestFlow {

    ...

    func testStart(startTime: Date, allDutIndexSnMap: Dictionary<Int, String>) {

        ...

         for i in 0...plistTestItems.count - 1 {

            let pItem = plistTestItems[i]

            

            //add into DispatchGroup

            queue.async(group: group) {

                

                let eachfunc = testList!.testItemScript[pItem.Script]

                if eachfunc != nil {

                    ...

                    var resultItem = eachfunc!(container)

                    ...

    }

}

2025年8月7日 星期四

大杯無鹽

關羽跟張飛都掛了

劉備找孔明訴苦 劉備:「雲長魂歸故里,如今三弟也溘然長逝,真乃大悲啊」 孔明:「甜度?」

劉備:「大悲無言」

孔明:「我是問甜度,不是加不加鹽…」

Lean 4 極簡教學 (Using VS Code on macOS)

 1. Install Lean Environment: https://lean-lang.org/install/ 試著完Step one, two, three 2. 在VS code下,建一新的project: 取名Hello_World 3. 嘗試執行Main.lea...