modalsoul’s blog

これは“失敗”と呼べるかもしれないが、ぼくは“学習体験”と呼びたい

LeetCode 14. Longest Common Prefix

LeetCode Problem No.14.

No.13 is here.

modalsoul.hatenablog.com

14. Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings. If there is no common prefix, return an empty string "".

Example 1

Input: strs = ["flower","flow","flight"]
Output: "fl"

Example 2

Input: strs = ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.

Constraints

1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] consists of only lower-case English letters.

Code

object Solution {
    def longestCommonPrefix(strs: Array[String]): String = {
        def run(targets:Array[String], acc:String): String = {
            if(!targets.head.isEmpty && targets.tail.forall{ x => !x.isEmpty && x.head == targets.head.head }) 
                run(targets.map(_.tail), acc+targets.head.head)
            else acc
        }
        run(strs, "")
    }
}

Methods

Compare n-th character in each strs.

  • All n-th character are same, accumulate n-th character and increment n.
  • All n-th character are not same, return accumulated characters.

Results

Runtime: 679 ms, faster than 72.08% of Scala online submissions for Longest Common Prefix. Memory Usage: 71.8 MB, less than 11.69% of Scala online submissions for Longest Common Prefix.

LeetCode 13. Roman to Integer

LeetCode Problem No.13.

No.12 is here.

modalsoul.hatenablog.com

13. Roman to Integer

Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M.

Given a roman numeral, convert it to an integer.

Example 1

Input: s = "III"
Output: 3
Explanation: III = 3.

Example 2

Input: s = "LVIII"
Output: 58
Explanation: L = 50, V= 5, III = 3.

Example 3

Input: s = "MCMXCIV"
Output: 1994
Explanation: M = 1000, CM = 900, XC = 90 and IV = 4.

Constraints

1 <= s.length <= 15
s contains only the characters ('I', 'V', 'X', 'L', 'C', 'D', 'M').
It is guaranteed that s is a valid roman numeral in the range [1, 3999].

Code

object Solution {
    def romanToInt(s: String): Int = {
        def toInt(ss:String, i:Char, v:Char, x:Char, num:Int):(Int, Int) = {
          val (a, b) = ss.span(_ == i)
          if(b.isEmpty) (a.length*num, a.length)
          else if(b.head == x) (num*9, 2)
          else if(b.head == v) (num*4, 2)
          else (a.length*num, a.length)
        }
        def toIntV(ss:String, i:Char, num:Int) = {
          if(ss.tail.takeWhile(_ == i).isEmpty) (num*5, 1) else (num*6, 2)
        }

        var index = 0
        var res = 0
        while(index < s.length) {
          val (n, inc) = s(index) match {
            case 'I' => toInt(s.drop(index), 'I', 'V', 'X', 1)
            case 'V' => toIntV(s, 'I', 1)
            case 'X' => toInt(s.drop(index), 'X', 'L', 'C', 10)
            case 'L' => toIntV(s, 'X', 10)
            case 'C' => toInt(s.drop(index), 'C', 'D', 'M', 100)
            case 'D' => toIntV(s, 'C', 100)
            case 'M' => toInt(s.drop(index), 'M', ' ', ' ', 1000)
          }
          res = res + n
          index = index + inc
        }
        res
    }
}

Results

Runtime: 516 ms, faster than 94.58% of Scala online submissions for Roman to Integer. Memory Usage: 53.1 MB, less than 89.16% of Scala online submissions for Roman to Integer.

AWS StepFunctionsのStateMachine内で値を引き回す方法

AWS StepFunctionsで定義したStateMachineで、実行時に与えられる値をStateを横断して参照するようなケースを考える。

ex.

以下のようなステートマシンで、実行時にparamが与えられるとき、Step2でも同じくparamを参照したい

flowchart TD Start(Start) -->|param| Step1[Step1] Step1 -->|param| Step2[Step2] Step2 --> End(End)

ResultPath

ResultPathを使うことで、InputをOutputへ引き回し、伝播させることができる

docs.aws.amazon.com

結果を破棄し、元の入力を渡す

ResultPathにnullを指定すると、実行したStateの結果を破棄し、元の入力をそのまま出力することができる

ex.)

StateMachine

{
  "StartAt": "Step1",
  "States": {
    "Step1": {
      "Type": "Pass",
      "Result": "hogefuga",
      "ResultPath": null,
      "Next": "Step2"
    },
    "Step2": {
      "Type": "Pass",
      "Result": "$.param",
      "End": true
    }
  }
}

Input

{
  "param": "input value"
}

Output

Step1の結果hogefugaが破棄され、Inputと同じ値が出力される。これでStep2でもStep1と同じInputを参照できる

{
  "param": "input value"
}

結果を入力に含める

元の入力に、指定したキーの値として実行したStateの結果を入れ、出力することができる

ex.)

StateMachine

{
  "StartAt": "Step1",
  "States": {
    "Step1": {
      "Type": "Pass",
      "Result": "hogefuga",
      "ResultPath": "$.result",
      "Next": "Step2"
    },
    "Step2": {
      "Type": "Pass",
      "Result": "$.param",
      "End": true
    }
  }
}

Input

{
  "param": "input value"
}

Output

Step1の結果hogefugaがResultPathに指定したキーresultの値としてInputに追加され出力される。

{
  "param": "input value",
  "result": "hogefuga"
}

M5Atom LiteでSG90互換サーボを操作する

M5Atom LiteでSG90互換サーボモータを使ったときのメモ

モノ

ライブラリ

www.arduino.cc

コード

GPIOは21、制御パルスは500μs~2250μs、中立位置は1500μs

中立位置からスタートして、最大〜最小を往復する

#include <M5Atom.h>
#include <ESP32Servo.h>
Servo servo;

int pmin = 750;
int pmax = 2250;
int p = 1500;
int pd = 2;

void setup() {
  M5.begin();
  servo.setPeriodHertz(50);
  servo.attach(21, pmin, pmax);
}

void loop() {  
  servo.write(p);
  Serial.printf("p = %d\n", p);

  p += pd;
  if (p > pmax) {
    p = pmax;
    pd = -pd;
  } else if (pmin > p) {
    p = pmin;
    pd = -pd;
  }

  delay(10);
}

M5StickC PlusとM5Stack用拡張ハブユニットで複数Groveポートを使う

M5Stack用拡張ハブユニットのメモ

モノ

M5Stack用拡張ハブユニット

M5Stack用拡張ハブユニット

  • スイッチサイエンス
Amazon

コード

土壌水分センサユニットとリレーユニットの両方を接続し、計測値に応じてリレーを作動させる。

土壌水分センサユニットのアナログ値の取得にG33を、リレーの動作にG32を使用。

動作

M5StickC Plusと土壌水分センサユニットで水分量を計測する

M5Stack用土壌水分センサユニットのメモ

モノ

M5Stack用土壌水分センサユニット

ユニットの裏面(ラベルがついていない面)に、ロータリースイッチがありこれでデジタル値の閾値を設定できる。

コード

動作

M5Atom LiteとM5Stack用ミニリレーユニットで電源を操作する

M5Atom LiteとRelay Unit(M5Stack用ミニリレーユニット)を使ったときのメモ

モノ

Atom Lite

M5Stackシリーズで最も小さいモデル。

今回使ったのは正面にRGB LED、ボタンを搭載したLite

↓は同ATOMシリーズのEcho

Relay Unit(M5Stack用ミニリレーユニット)

最大3 A(24 VDCあるいは120 VAC)

コード

0.5s毎にLEDを点滅させる

#include <M5Atom.h>

void setup() {
  M5.begin();
  pinMode(26, OUTPUT);
}

void loop() {
 digitalWrite(26, HIGH);
 delay(500);
 digitalWrite(26, LOW); 
 delay(500);
}

動作