ããã°ã©ãã³ã°è¨èªAmberã®ç´¹ä»(ãã®1)
3å¹´ã¶ãã«æ´æ°ãã¾ãããã®ï¼å¹´éã«ã(éä¸1年以ä¸å¥ã®äºããã£ã¦ãã¾ããã)èªä½ã®è¨èªã¨ãã®å¦çç³»ã®éçºã¯ç¶ãã¦ãã¾ãããããããç´¹ä»è¨äºãæ¸ãå§ãããã¨æãã¾ããホームページã¯æ¢ã«ããã¾ããããã¡ãã¯æ¨å¹´ã®å¤ããæ´æ°ãã¦ããªãã®ã§å 容ãå¤ããªã£ã¦ãã¾ããæ¬è¨äºãå ã«ãã¦å¾ã§æ´æ°ãã¾ãã
è¨èªã®ååã¯Amberã¨è¨ãã¾ããAmberã¨ã¯æ¥æ¬èªã§ç¥çã¨ããæå³ã§ããå®ã¯ååã®è¨èªå¦çç³»ãããã¤ãåå¨ããã®ã§ãã(larsivi / amber / wiki / Home — Bitbucket, GitHub - eknkc/amber: Amber is an elegant templating engine for Go Programming Language, inspired from HAML and Jade, The Amber Programming Languageãªã©)ããã®ååã«ã¯æçãããã¾ãããããå çã«ã¤ãã¦é ããååã§ããã¨ãããã¨ãããã®ã§ç§ã使ç¨ããã¦é ãã¾ãã
Amberã¯åçåã®ã¹ã¯ãªããè¨èªã§ã以ä¸ã®æ§ãªç¹å¾´ãæã¡ã¾ãã
- åå³è±¡æ§
- ãã¼ã¿è¡¨ç¾ã¯é¢æ°å + å¼æ°
- ãããã¿ã¤ããã¼ã¹ã®ãªãã¸ã§ã¯ãã·ã¹ãã
- é¢æ°ã¯å ¨ã¦é¨åé¢æ°ã§ããé¢æ°å士ã¯åä½µå¯è½
åå³è±¡æ§ã¨ã¯ããã°ã©ã ã¨ã³ã¼ããåã表ç¾ãæã¤ã¨ããæ§è³ªã§Lispç³»è¨èªã«è¦ããããã®ã§ããä½ãããã¼ã¿è¡¨ç¾ã¯ã³ã³ã¹ã»ã«ã§ã¯ãªããé¢æ°åfã¨å¹¾ã¤ãã®å¼æ°e1,e2,...,enãããªã f{e1, e2, ..., en} ã¨ããå½¢å¼ã§ããåå³è±¡æ§ã¨ãããã¿ã¤ããã¼ã¹ã¨ããã®ã¯ã¡ã¿ããã°ã©ãã³ã°ãå¼·ãæèããé¸æã§ããAmberã¯çæçããã°ã©ãã³ã°ãèªå·±åæ çããã°ã©ãã³ã°ãªã©ãé常ã«å¹³æã«è¡ããããã«ä½ããã¦ãã¾ããã¡ã¿ããã°ã©ãã³ã°ãéè¦ããäºã®å ·ä½çãªç®çã¯ã¾ãå¾ã§èª¬æãã¾ããAmberã®é¢æ°ã¯å¼æ°ã®ãã¿ã¼ã³åã³ã¬ã¼ãç¯ã«ãã£ã¦ãã®å®ç¾©åãéå®ãããäºã§é¨åé¢æ°ã¨ãªããããã«é¨åå士ãåä½µããäºã«ãã£ã¦ããããªé¢æ°ãä½ãäºãåºæ¥ã¾ãã
ãã°ã®å ±åãã¢ã¤ãã¢ã»ãæè¦ãããã ãã¾ãã¨å¤§å¤ãããããã§ãããã®å ´åã¯[twitter:@9_ties]ã«ãé¡ããã¾ããAmberã®ä»æ§ã¯ã¾ã åæãã¦ããªãã®ã§ç´°ããªå¤æ´ãä»å¾ãç¶ãã¾ãããã®ææ¸ã¯ææ°ã®ä»æ§ã«åãããããé å¼µãã¾ãããééã£ã¦ããããã¿ã¾ããã
ãã«ãã»ã¤ã³ã¹ãã¼ã«
Amberã®ã¤ã³ã¿ããªã¿amberã¯ä»¥ä¸ã®æé ã§ãã«ãã»ã¤ã³ã¹ãã¼ã«ã§ãã¾ãããã«ãã«ã¯Linuxç°å¢ã¨git,make,binutilsãå¿ è¦ã§ããããã©ã«ãã§ã¯/usr/lib/amber/以ä¸ã«ã©ã¤ãã©ãªç¾¤ãã/usr/bin/以ä¸ã«amberã¨ããã¹ã¯ãªãã1ã¤ãã¤ã³ã¹ãã¼ã«ããã¾ããã³ã³ãã£ã®ã¥ã¬ã¼ã·ã§ã³ãã¡ã¤ã«ã¯ã¾ã ç¨æãã¦ããªãã®ã§ããææ°ã§ããå¿ è¦ãªãã°Makefileä»ãæ¸ãç´ãã¦ä¸ãããã¤ã³ã¹ãã¼ã«å ã¯/usr/lib/ã¾ãã¯LD_LIBRARY_PATHã«è¨å®ããããã£ã¬ã¯ããªã«ãã¦ãã ããã
% git clone https://github.com/nineties/amber.git % cd amber % make % sudo make install
ãã«ãã¯ä»¥ä¸ã®æé ã§ãã¼ãã¹ãã©ããã³ã°ã«ããè¡ããã¾ãã
- ã¢ã»ã³ããªè¨èªã§æ¸ãããrlcã¨ããç°¡åãªæç¶ãåè¨èªã®ã³ã³ãã¤ã©ãGNU Assemblerã§ã³ã³ãã¤ã«ã
- rlcã§rlciã¨ããç°¡åãªLispã¤ã³ã¿ããªã¿ãã³ã³ãã¤ã«ã
- rlciã§rlvmã¨ããamberã®ä»®æ³ãã·ã³ã®ã¢ã»ã³ããªã³ã¼ããçæããGNU Assemblerã§ã³ã³ãã¤ã«ã
- rlciã§rlvmã®ãã¤ãã³ã¼ãç¨ã®ãªã³ã«(ããèªä½ãrlvmä¸ã§åã)ãã³ã³ãã¤ã«ã
- rlciã§rlvmã®ãã¤ãã³ã¼ãç¨ã®éã¢ã»ã³ãã©(ããèªä½ãrlvmä¸ã§åã)ãã³ã³ãã¤ã«ã
- rlciã§amberã®ã½ã¼ã¹ã³ã¼ããã³ã³ãã¤ã«ããrlvmç¨ã®ãªãã¸ã§ã¯ããã¡ã¤ã«(*.rlo)ãçæã
- ä¸ã§ä½æãããªã³ã«ã使ã£ã¦*.rloããªã³ã¯ã
Hello World
% amber
ã§amberã®ã·ã§ã«ãèµ·åãã¾ãã(注:ã¾ã readlineãhistoryãå®è£
ãã¦ãã¾ããã®ã§è¡ç·¨éãåºæ¥ã¾ããããã®ãã¡å®è£
ãã¾ãã)
ãããã¯ãã¡ã¤ã«ã«ããã°ã©ã ãæ¸ãã¦
% amber hoge.ab
ã¨å®è¡ãã¾ããAmberã¹ã¯ãªããã®æ¡å¼µåã¯.abã§ãã
ã¾ãã¯Hello Worldã§ãã
amber:1> puts("Hello Amber!") Hello Amber! => nil
ã·ã§ã«ãçµäºãããçºã«ã¯exitã¨ã¿ã¤ããã¾ãã
ä»ã«ãå¹¾ã¤ãè¦ã¦ã¿ã¾ããããamberã·ã§ã«ã§ã¯ç´åã®è¨ç®çµæã$ã§åç §ããäºãåºæ¥ã¾ããã¾ãnçªç®ã®ããã³ãã(amber:n> ...)ã®çµæã$nã§åãåºãã¾ããä¾ãã°ä»¥ä¸ã®2 * $ã§ã¯ 2Ã3ãã$2 / $3ã§ã¯3å²ã6ãè¨ç®ãã¦ãã¾ãã
amber:2> 1 + 2 => 3 amber:3> 2 * $ => 6 amber:4> $2 / $3 => 0.5
ã¾ããæ´æ°ã¯æ¡ãããµããã¨èªåçã«å¤åé·æ´æ°ã«å¤æããã¾ãã
amber:5> 7 ^ 160 => 1643184774938171857917000410556544806341837419599523497069764671233207565562287891877564323818254449486910838997871467298047369612896001
åºæ¬çãªæ°å¦é¢æ°ã¯å®è£ ãã¦ããã¾ãã®ã§ãã¨ããããé¢æ°é»åã¨ãã¦ãããã使ããã¨æãã¾ãã
amber:6> import math => Module{math} amber:7> math::sin(1) => 0.8414709848078965
ã¢ã¸ã¥ã¼ã«å¤æ°ã¯ :: ã¨ããè¨å·ã使ã£ã¦åç §ãã¾ããimportã®ãªãã·ã§ã³ã§æå®ãã¦ç¾å¨ã®åå空éã«æã£ã¦ããäºãåºæ¥ã¾ããä¾ãã°ä»¥ä¸ã®æ§ã«ããã¨math::ãªãã§sqrtãå¼ã¹ã¾ãã
amber:8> import math (sqrt) => Module{math} amber:9> sqrt(2) => 1.414213562373095
ä»ã«ãããç¹å®ã®å¤æ°ä»¥å¤ãæã£ã¦ããããå ¨ã¦æã£ã¦ããã¨ãã£ãäºãåºæ¥ã¾ãã
amber:10> import math hiding (tan, cos) => Module{math} amber:11> log(2) => 0.6931471805599454 amber:12> cos(1) Exception: UndefinedVariable{cos} amber:12> import math (*) => Module{math} amber:13> cos(1) => 0.5403023058681398
ã·ã³ãã«ã¯å¤æ°åãªã©ã®å種ãå称ãã表ããã¼ã¿åã§ããAmberã®èå¥å([A-Za-z_][A-Za-z0-9_]*[!?]?ã¨ããææ³)ã«å¯¾å¿ããã·ã³ãã«ã¯ã·ã³ã°ã«ã¯ãªã¼ãã§ä»¥ä¸ã®æ§ã«è¨è¿°ããã¨ä½æåºæ¥ã¾ãã
amber:14> 'this_is_a_symbol => this_is_a_symbol
ä¸è¬ã®æååã«ã¤ãã¦ã¯to_symã¡ã½ããã§ã·ã³ãã«åã§ãã¾ãã
amber:15> "this is a symbol".to_sym() => this is a symbol
ã·ã³ãã«ã¯è¡¨ã«ç»é²ãããåãæååã«å¯¾å¿ããã·ã³ãã«ã¯å¸¸ã«ã¡ã¢ãªä¸ã§åä¸ã®ãã¼ã¿ã§ããäºãä¿è¨¼ããã¾ããåãå¤ãå¦ãã¯æ¼ç®å == ã§ããã¼ã¿ã®å®ä½ãåä¸ãå¦ãã¯é¢æ°identical?ã§èª¿ã¹ããã¾ãã
amber:16> "abc" == "abc" => true amber:17> identical?("abc", "abc") => false amber:18> 'abc == 'abc => true amber:19> identical?('abc, 'abc) => true
ãã®ä»ãåå§çãªãã¼ã¿åã«ã¯çå½å¤true,falseã¨æå³ã®ç¡ãå¤ã§ããäºã表ãnilãããã¾ãã
æ´¾çåã®ä¾ã¨ãã¦ã³ã³ãããç´¹ä»ãã¾ããè¯ã使ãã³ã³ããåã¯ã¿ãã«ã»ãªã¹ãã»é åã»ãã¼ãã«(ããã·ã¥è¡¨)ã§ããæ¼ç®å[ ]ã§åè¦ç´ ã«ã¢ã¯ã»ã¹åºæ¥ã¾ãããã®ä»ã³ã³ããã®ç¹å¾´ã«å¿ããã¡ã½ãããç¨æããã¦ãã¾ãã
amber:20> (1,2,3) => (1, 2, 3) amber:21> [1,2,3,4,5] => [1, 2, 3, 4, 5] amber:22> Array{1, 2, "foo", "bar"} => Array{1, 2, "foo", "bar"} amber:23> Table{("one", 1), ("two", 2), ("three", 3)} => Table{("three", 3), ("two", 2), ("one", 1)} amber:24> $["two"] => 2
å¤æ°ãå®ç¾©ããå ´åã«ã¯ := ã¨ããè¨å·ãç¨ãã¾ããå¤ãã®ã¹ã¯ãªããè¨èªã§ã¯ãããªãå¤æ°ã«ä»£å ¥ãåºæ¥ã¾ãããAmberã§ã¯å®ç¾©ãå¿ è¦ã§ãã
amber:25> x := 2 => 2 amber:26> x + 1 => 3 amber:27> x = 3 => 3 amber:28> x => 3 amber:29> y = 1 Exception: UndefinedVariable{y}
å¶å¾¡æ§é ã¯ifæ, whileæ, foræ, try-catchæãªã©æç¶ãåè¨èªã®æ¨æºçãªãã®ãå®è£ ããã¦ãã¾ããè¤æ°è¡ã®ã³ã¼ããããã¯ã¯ { ... } ã§å²ã¿ã¾ãã
amber:29> if [1,5,3,4].include?(3) { amber:29~ puts("found") amber:29~ } else { amber:29~ puts("not found") amber:29~ } found => nil amber:30> i := 0 => 0 amber:31> while (i < 10) amber:31~ i += 1 => nil amber:32> i => 10 amber:33> for i in 1..10 amber:33~ puts i 1 2 3 4 5 6 7 8 9 10 => nil amber:34> for v in [1,2,3,4] amber:34~ puts v 1 2 3 4 => nil
ãã¨ã¯shift-resetãã¼ã¹ã®éå®ç¶ç¶ãå®é¨çã«å®è£
ãã¦ãã¾ããAmberã®ã¢ããªã±ã¼ã·ã§ã³ã§ã¯å¯¾è©±åã»ãã·ã§ã³ãç©æ¥µçã«ä½¿ã£ã¦ãããã¨æã£ã¦ããã®ã§ç¶ç¶ã¯ãã£ãæ¹ãè¯ãã ããã¨ããèãã§ãããã ããããå®è£
ããå¯è½æ§ãèããã«ã¬ãã¼ã¸ã³ã¬ã¯ã¿ãå®è£
ãã¦ãã¾ã£ãã®ã§ã大åå®è£
ãé¢åãªäºã«ãªã£ã¦ãã¾ãã¾ãããå®è£
ã«ããã£ã¦ã¯ä»¥ä¸ãåèã«ããã¦é ãã¾ããã
益子萌,浅井健一(2009)「MinCamlコンパイラにおけるshift=resetの実装」PPL09
amber:35> cont := nil => nil amber:36> reset () -> { amber:36~ puts("foo") amber:36~ shift k -> { cont = k } amber:36~ puts("bar") amber:36~ shift k -> { cont = k } amber:36~ puts("baz") amber:36~ } foo => <#Function> amber:37> cont(nil) bar => <#Function> amber:38> cont(nil) baz => nil
ãã¼ã¿ã®è¡¨ç¾
Amberã®ãã¼ã¿ã¯æ°å¤åãæåååãªã©ã®åå§çãªãã¸ã§ã¯ã(ã¢ãã )ã¨ãã·ã³ãã«fã¨å¹¾ã¤ãã®å¼æ°e1,e2,...,enãããªãf{e1, e2, ..., en}ã¨ããå½¢å¼ã®æ´¾çãªãã¸ã§ã¯ããããªãã¾ããAmberã§ã¯fããªãã¸ã§ã¯ãã®ããããnãã¢ãªãã£ã¨å¼ãã§ãã¾ãã(ã¢ãªãã£ã¯ãããã®å±æ§ã§ã¯ãªãã¦ãªãã¸ã§ã¯ãã®å±æ§ã§ããé常ã®ç¨æ³ã¨ç°ãªãã®ã§å¥å¦ããããã¾ããããä»ã«è¯ãååãæãæµ®ãã³ã¾ããã§ããã)
fullformã¨ããé¢æ°ã§ä»»æã®ãªãã¸ã§ã¯ãããã®å½¢å¼ã§æåååããäºãã§ãã¾ããã¾ãã.head, .arity, .argumentsã§ãããããåãåºãäºãåºæ¥ã¾ãã(fullformã¨ããå¼ç§°ã¯Mathematicaããé ãã¦ãã¾ãã)
amber:39> obj := (1,2,[3,4]) => (1, 2, [3, 4]) amber:40> fullform(obj) => "Tuple{1, 2, List{3, 4}}" amber:41> obj.head => Tuple amber:42> obj.arity => 3 amber:43> obj.arguments => [1, 2, [3, 4]]
ãã¡ãããfullformãç´ã«å ¥åãã¦ãè¯ãã§ãã
amber:44> List{1, List{2, 3}, List{4, 5}} => [1, [2, 3], [4, 5]]
ã¢ãã ã¯æ´¾çãªãã¸ã§ã¯ãã§ã¯ãªãã®ã§fullformã¯ããã¾ãããããããã«ããããã¨å¼ã°ããã·ã³ãã«ãç´ä»ãããã¦ããã¢ãªãã£ã0ã®ãªãã¸ã§ã¯ãã¨ãã¦æ´¾çãªãã¸ã§ã¯ãã¨åæ§ã«åãæ±ãäºãåºæ¥ã¾ãã
amber:45> "abc".head => String amber:46> "abc".arity => 0 amber:47> "abc".arguments => [] amber:48> fullform("abc") => "\"abc\""
åå³è±¡æ§
Amberã®ããã°ã©ã ããèªä½ãAmberã®ãã¼ã¿ã¨ãã¦åãæ±ãäºãåºæ¥ã¾ããLispã¨åæ§ã«ã¯ãªã¼ã(è¨å·')ãå©ç¨ããã¨è©ä¾¡å¨ã®è©ä¾¡ãæ¢ãã¦æ§ææ¨ãåãåºãäºãåºæ¥ã¾ããåºåã¯æ´å½¢ããã¾ãããfullformã使ãã°é常ã®ãã¼ã¿ã¨åãæ§é ã§ããäºãå¤ãã¾ããã¾ããé¢æ°evalfullã«ãã£ã¦ãããè©ä¾¡ããäºãåºæ¥ã¾ãã
amber:49> '{ amber:49~ s := 0 amber:49~ for i in 1..100 amber:49~ s += i^2 amber:49~ s amber:49~ } => { s := 0 for i in 1..100 { s += i^2 } s } amber:50> fullform($) => "Block{Define{s, 0}, For{i, Range{1, 100}, Block{AddAssign{s, Pow{i, 2}}}}, s}" amber:51> evalfull($49) => 338350
æºã¯ãªã¼ã(è¨å·`)ã¨ã¢ã³ã¯ãªã¼ã(è¨å·!)ãç¨æããã¦ãã¦ãæºã¯ãªã¼ãã®ä¸ã§ã¯ã¢ã³ã¯ãªã¼ããããé¨åã ãè©ä¾¡ãè¡ããã¾ãã
amber:52> `(1 + !(2 + 3)) => 1 + 5
é¢æ°
é¢æ°ãè¨å· := ãç¨ãã¦å®ç¾©ãã¾ãã
amber:53> f(x) := x + 1 => <#Function> amber:54> f(1) => 2
é¢æ°ã®å¼æ°é¨ã«ã¯å種ãã¿ã¼ã³ãæå®ããäºãåºæ¥ã¾ããä¾ãã°å®ç¾©åãæ´æ°ã®ã¿ã«éå®ããé¨åé¢æ°ã¯ä»¥ä¸ã®æ§ã«å®ç¾©ãã¾ãããã®é¢æ°ã«æ´æ°ä»¥å¤ã渡ãã¨MatchingFailedä¾å¤ã¨ãªãã¾ãã
amber:55> g(x @ Int) := x + 1 => <#Function> amber:56> g(1) => 2 amber:57> g(1.5) Exception: MatchingFailed{domain = (x @ Int), [1.5]}
å¼æ°é¨ã«ä½ããã®ãã©ã¼ã ãæ¸ãã¨ãã£ã¨è¤éãªãã¿ã¼ã³ãããã³ã°ãåºæ¥ã¾ãã
amber:57> g(Foo{x, y}) := (x, y) => <#Function> amber:58> g('Foo{1, 2}) => (1, 2) amber:59> g(x + y) := (x, y) => <#Function> amber:60> g('(2 + 3)) => (2, 3)
以ä¸Amberã§ä½¿ç¨ããäºãåºæ¥ããã¿ã¼ã³ãåæãã¦ããã¾ãã
DontCareãã¿ã¼ã³(è¨å·_)
amber:61> g([_, _, x, _]) := x => <#Function> amber:62> g([1,2,3,4]) => 3
ãªãã©ã«ãã¿ã¼ã³(å®æ°å¤)
amber:63> g(0) := "zero" => <#Function> amber:64> g(0) => "zero" amber:65> g('[x,y,z]) := "matched" => <#Function> amber:66> g('[x,y,z]) => "matched"
å¯å¤é·ãã¿ã¼ã³(è¨å·...)
amber:67> g(Foo{_, _, ...}) := "Foo object with arity >= 2" => <#Function> amber:68> g('Foo{1, 2, 3}) => "Foo object with arity >= 2" amber:69> g('Foo{1}) Exception: MatchingFailed{domain = (Foo{_, _, ...}) | ('[x, y, z]) | (0) | ([_, _, x, _]) | (x + y) | (Foo{x, y}) | (x @ Int), [Foo{1}]} amber:69> g([_, _, rest...]) := rest => <#Function> amber:70> g([1,2,3,4,5,6]) => [3, 4, 5, 6]
ã¬ã¼ãç¯
amber:71> g(x) when x > 0 := "positive value" => <#Function> amber:72> g(1) => "positive value"
ORãã¿ã¼ã³
amber:73> g(_ @ Int or _ @ Float) := "a number" => <#Function> amber:74> g(1) => "a number" amber:75> g(1.0) => "a number"
ãã¨ããã¿ã¼ã³ã§ã¯ãªãã®ã§ããããã¼ã¯ã¼ãå¼æ°ã使ãã¾ãã
amber:76> g(x = 0, y = 1) := (x, y) => <#Function> amber:77> g(x = 1, y = 2) => (1, 2) amber:78> g(y = 3) => (0, 3)
ãã®æãgã¨ããååã§å®ç¾©ãããå ¨ã¦ã®é¢æ°ã¯æ¬¡ã ã«åä½µãããä¸ã¤ã®é¢æ°ã«ãªã£ã¦ãã¾ããç¾å¨gã®å®ç¾©åãã©ã®ããã«ãªã£ã¦ãããã¯æ¬¡ã®ããã«ãã¦è¦ããã¨ãåºæ¥ã¾ãã
amber:79> g.domain => domain = (x = 0, y = 1) | (_ @ Int or _ @ Float) | (x) when x > 0 | ([_, _, rest...]) | (Foo{_, _, ...}) | ('[x, y, z]) | (0) | ([_, _, x, _]) | (x + y) | (Foo{x, y}) | (x @ Int)
gã«æ¸¡ãããå¤ã¯domainã®ä¸ããé çªã«ãã§ãã¯ããæåã«ãããããé¢æ°ã®å®ä½ãå¼ã°ãã¾ãã(å®éã«ã¯å®è¡æã«å¤å°ã®æé©åãè¡ããã¦åçã«ãããã³ã°ãè¡ããã¤ãã³ã¼ããçæããã¦ãã¾ãã)
ä¸ã®ä¾ãè¦ãã°åããããã«å¸¸ã«æå¾ã«å®ç¾©ããããã®ãåªå ãããã®ã§ãä¸è¬çãªå ´åãå ã«å®ç¾©ãç¹æ®ãªå ´åãå¾ã«æ¸ãã¾ããä¾ãã°ãã£ããããæ°ãè¿ãé¢æ°fibã¯ä»¥ä¸ã®ããã«æ¸ããã¨ãåºæ¥ã¾ãã
amber:80> fib(n) := fib(n-1) + fib(n-2) => <#Function> amber:81> fib(0) := 0 => <#Function> amber:82> fib(1) := 1 => <#Function> amber:83> fib(20) => 6765
å¤æ°å®ç¾©ãå¢ãã¦ããã®ã§ä¸æ¦åæåãã¾ãããã
amber:84> .clear() => nil
ç¡åé¢æ°ã¯ä»¥ä¸ã®ããã«ãã¦ä½ãäºãåºæ¥ã¾ãã
amber:85> (x, y) -> x + y => <#Function> amber:86> $(2, 3) => 5
1å¼æ°ã®é¢æ°ã¯é常ã«è¯ã使ãã®ã§ã1å¼æ°ã®æã ãã¯å¼æ°ã®æ¬å¼§ãçãäºãåºæ¥ã¾ãã
amber:87> x -> x + 1 => <#Function> amber:88> $(1) => 2
Amberã®é¢æ°ã¯ãã¡ã¼ã¹ãã¯ã©ã¹ãªãã¸ã§ã¯ããªã®ã§ä»ã®é¢æ°ã«æ¸¡ãäºãåºæ¥ã¾ãã
amber:89> [1,2,3,4].map(x -> x + 1) => [2, 3, 4, 5]
é¢æ°f,gã®åä½µã¯æ¼ç®å|ã«ãã£ã¦è¡ãäºãåºæ¥ã¾ãããã®å ´åå·¦å´ã®é¢æ°ããããã³ã°ã«ããã¦é«ãåªå 度ãæã¡ã¾ãã
amber:90> x @ Int -> "integer" | x @ Float -> "floating point" | x @ String -> "string" => <#Function> amber:91> $.domain => domain = (x @ Int) | (x @ Float) | (x @ String) amber:92> $90(1) => "integer" amber:93> $90(1.0) => "floating point" amber:94> $90("Hello") => "string"
ãã¨ãã¬ãã·ã«ã«ã¹ã³ã¼ãã®ã¯ãã¼ã¸ã£ãããã¾ãã
amber:95> make_counter() := { amber:95~ n := 0 amber:95~ () -> { n += 1 } amber:95~ } => <#Function> amber:96> cnt1 := make_counter() => <#Function> amber:97> cnt2 := make_counter() => <#Function> amber:98> cnt1() => 1 amber:99> cnt1() => 2 amber:100> cnt2() => 1 amber:101> cnt1() => 3 amber:102> cnt2() => 2
ãã³ãã¬ã¼ãã¡ã¿ããã°ã©ãã³ã°
æ¼ç®å[ ]ã«é¢æ°fã渡ãã¨fã«ãããããé¨åãæ¸ãæããã¨ããåä½ããã¾ãã
amber:103> obj := 'Foo{1,2,3} => Foo{1, 2, 3} amber:104> obj[ 1 -> 3 | 2 -> 5 ] => Foo{3, 5, 3}
1 -> 3 | 2 -> 5ã®é¨åãé¢æ°ã§ãããããè¦ããªãããæå³çã«ææ³ãä½ã£ã¦ãã¾ãã
ããã使ã£ã¦ãã³ãã¬ã¼ãã¡ã¿ããã°ã©ãã³ã°ãé常ã«ç°¡åã«å®ç¾ããäºãåºæ¥ã¾ããä¾ãã°å f(1) + f(2) + f(3) + ... + f(n) ãæ±ããæ¬ä¼¼ã³ã¼ãã¯ä»¥ä¸ã®ããã«æ¸ãã¾ãã
amber:105> '{ amber:105~ s := 0 amber:105~ for i in 1..n amber:105~ s += f(i) amber:105~ s amber:105~ } => { s := 0 for i in 1..n { s += f(i) } s }
ãããå ã»ã©ã®æ¹æ³ã§æ¸ãæããã°å®è¡å¯è½ãªã³ã¼ããçæããäºãåºæ¥ã¾ãã
amber:106> $[ 'f(i) -> '(1/i^2) | 'n -> 100 ] => { s := 0 for i in 1..100 { s += 1 / i^2 } s } amber:107> evalfull($) => 1.634983900184892
ãããå ã«ãã¯ããä½ã£ã¦ã¿ã¾ããããAmberã¯ãã©ã¼ã ãmacroã¨ããé¢æ°ã§å¤æãã¦ããè©ä¾¡ãã¾ããæ¨æºã§ã¯ä»¥ä¸ã®ãããªãã©ã¼ã ã«å¯¾ãããã¯ããå®ç¾©ããã¦ãã¾ãã
amber:108> macro.domain => domain = (e @ Import{mods, asname, option}) | (DefTrait{head}) | (DefClass{head, fields}) | (WithSlots{obj, init}) | (When{args, guard} -> body) | (Domain{args, List} -> body) | ((for i in a..b body)) | ((for i in container body)) | (ArithAssign{x[idxs...], e, op}) | (x[idxs...] = e) | (x[idxs...]) | (x |= y) | (x %= y) | (x //= y) | (x /= y) | (x ^y) | (x **= y) | (x *= y) | (x -= y) | (x ++= y) | (x += y) | (x <=> y) | (x != y) | (x == y) | (x >= y) | (x <= y) | (x > y) | (x < y) | (x | y) | (x % y) | (x // y) | (x / y) | (x^y) | (x ** y) | (x * y) | (x ++ y) | (x - y) | (x + y) | (-x) | (+x) | (|x|) | (Assign{Send{obj, f, args}, e, g}) | (Define{Send{obj, f, args}, e, g}) | (Assign{Apply{f, args}, e, g}) | (Define{Apply{f, args}, e, g}) | (Send{obj, f, args} = e) | ((Send{obj, f, args} := e)) | ((Apply{f, args} := e)) | (Apply{f, args} = e) | (e)
ãããæ¡å¼µã㦠f(1) + f(2) + ... + f(n) ãè¨ç®ãããã¯ã sum(f, i, n) ãä½ãã¾ãããã"sum"ã®é¨åã¯sumã¨ããã·ã³ãã«èªä½ã«ããããã¦æ¬²ããã®ã§ãªãã©ã«ãã¿ã¼ã³('sum)ã使ãã¾ããã¾ãããã³ãã¬ã¼ãå ã§ä½¿ããã¦ããå¤æ°sã¯å±éå¾ã«ååãè¡çªããªãããã«ãã¦ãã¼ã¯ãªååã«å ã«ç½®ãæãã¦ããã¾ããsymbolã¢ã¸ã¥ã¼ã«ã®uniqueé¢æ°ã¯ã·ã³ãã«è¡¨ã«ç»é²ããã¦ããªã(å¾ã£ã¦ä»ã®ã·ã³ãã«ã¨å¸¸ã«ç°ãªã)ã·ã³ãã«ãçæãã¾ãã
amber:109> macro( ('sum)(f, i, n) ) := { amber:109~ template := '{ amber:109~ s := 0 amber:109~ for i in 1..n amber:109~ s += f(i) amber:109~ s amber:109~ } amber:109~ u := symbol::unique() amber:109~ template['s -> u]['f(i) -> f | 'i -> i | 'n -> n] amber:109~ } => <#Function>
ããã ãã§æ°ãããã©ã¼ã ã使ãäºãåºæ¥ã¾ããsã¨ããååã®å¤æ°ã使ã£ã¦ãæ£ããåä½ãã¦ããäºãåããã¨æãã¾ãã
amber:110> sum(i^2, i, 1000) => 333833500 amber:111> sum(1/s, s, 10000) => 9.787606036044345 amber:112> sum(sum(i*j, i, j), j, 100) => 12920425
Lispã§ã¯æºã¯ãªã¼ããç¨ãã¦ãã³ãã¬ã¼ããè¨è¿°ããæ¹å¼ã使ããã¾ãããç§ã¯ããã¦ããåãè¾¼ãæ¹å¼ãããå¤æããæ¹å¼ã®æ¹ãç解ããããã®ã§ã¯ãªããã¨èãã¦ãã¾ãããã¾ããä¸ã®æ¹å¼ãªãã°æºã¯ãªã¼ãã¨ã¢ã³ã¯ãªã¼ããç¨æããã¦ããªãè¨èªã«å¯¾ãã¦ããã³ãã¬ã¼ãã®ã¤ã³ã¹ã¿ã³ã·ã¨ã¼ã·ã§ã³ãç°¡åã«åºæ¥ã¾ãããã®æ¹å¼ã¯æ¨æºã©ã¤ãã©ãªã®å®è£ ã§ã使ã£ã¦ã¿ã¾ããããã³ã¼ãããã£ããã¨ãä»ã®æã¯è¯ãå°è±¡ãæã£ã¦ãã¾ããæºã¯ãªã¼ãæ¹å¼ã¨æ¯ã¹ããã¡ãªããã«ã¤ãã¦ã¯ã¾ã ååã«èå¯ãåºæ¥ã¦ãã¾ãããã¡ãªã¿ã«å ã»ã©ã®ãã¯ããæºã¯ãªã¼ãæ¹å¼ã§æ¸ãã¨ä»¥ä¸ã®æ§ã«ãªãã¾ãã
amber:113> macro( ('sum)(f, i, n) ) := { amber:113~ u := symbol::unique() amber:113~ `{ amber:113~ !u := 0 amber:113~ for !i in 1..!n amber:113~ !u += !f amber:113~ !u amber:113~ } amber:113~ } => <#Function>
ãã¼ãµçæ
åç¯ã®æ¹æ³ã¯Amberã®ãã³ãã¬ã¼ãã§Amberã®ã³ã¼ããçæããä¾ã§ããã®ã§Amberã®ææ³ã§å ¨ã¦æ¸ããã¨ãåºæ¥ã¾ãããããããä»ã®è¨èªã®æ§ææ¨ãä½æãããå ´åã«ã¯Amberã®ææ³ã使ããªãã®ã§å ¨ã¦fullformã§æ¸ããªããã°ãªããªããªã£ã¦ãã¾ãã¾ããããã§ããã¯ã©ããæ§æ解æå¨ã®ã¸ã§ãã¬ã¼ã¿ãç¨æããã¦ãããAmberå ã§ãã¼ãµãä½æåºæ¥ãããã«ãªã£ã¦ãã¾ãã
å®ã¯ããã¾ã§ä½¿ã£ã¦ããAmberã®ææ³èªä½ããã®ã¸ã§ãã¬ã¼ã¿ã§æ¸ããã¦ãã¾ããã¤ã³ã¿ããªã¿ã«ãããããçµã¿è¾¼ã¾ãã¦ããææ³ã¯ã¢ãã åã³fullformã®ã¿ã§ãèµ·åãã¦ããèªèº«ã®ãã¼ãµãã³ã³ãã¤ã«ããæ¹å¼ã«ãªã£ã¦ãã¾ãã(èµ·åãé ãã®ã¯ä¸»ã«ãã®çºã§ãããããããªã³ã³ãã¤ã«ã«ãã¾ãã)ããã¯lib/syntax/parse.abå ã§è¡ããã¦ãããæåã¯fullformã®ã¿ã§ã³ã¼ããæ¸ãâææ³ãå®ç¾©ããçºã®ææ³ãå®ç¾©ããâAmberã®ææ³ãå®ç¾©ããâãã¯ãã®ä»çµã¿ãä½ãâå種ãã¯ããå®ç¾©ããã¨ããæµãã«ãªã£ã¦ãã¾ãã
以ä¸ã¯ãã®ã¸ã§ãã¬ã¼ã¿ã使ã£ã¦CAST(C Abstract Syntax Tree)ã¨ããCè¨èªé¢¨ã®è¨èªãå®ç¾©ããã©ã¤ãã©ãªã®ä¸é¨ã§ããåºæ¬ã¯è§£æ表ç¾ææ³(PEG)ã§ãããã«ã³ãåºåãã®ãããªè¯ã使ããã¿ã¼ã³ããã¼ã¹ããçºã®delimitedãªã©ããã¤ãã¦ã¼ãã£ãªãã£ã追å ããã¦ãã¾ããä»ã«ã空ç½ã®æ±ããªã©ãç°ãªãã®ã§ã解説ãAmberã®ãã¼ã ãã¼ã¸ã«æ¸ãã¤ããã§ãã
primary_expr ::= identifier { Var.new($0) } | constant | string { StringL.new($0) } | "(" expr ")" { $1 } postfix_expr ::= postfix_expr "[" expr "]" { Subscript.new($0, $2) } | postfix_expr "(" delimited(assign_expr, ",") ")" { Call.new($0, $2) } | postfix_expr "." identifier { Select.new($0, $2) } | postfix_expr "->" identifier { Select.new(Deref.new($0), $2) } | postfix_expr "++" { PostInc.new($0) } | postfix_expr "--" { PostDec.new($0) } | primary_expr
Amberã®ã·ã§ã«ãã以ä¸ã®ããã«ä½¿ãã¾ãã
amber:114> import CAST => Module{CAST} amber:115> template := '<CAST>{ amber:115~ struct hoge { amber:115~ int x; amber:115~ double y; amber:115~ } amber:115~ int main(int argc, char **argv) { amber:115~ struct hoge st; amber:115~ st.x = 0; amber:115~ st.y = 2.0; amber:115~ printf("%d, %f\n", st.x, st.y); amber:115~ } amber:115~ } => CASTProgram{[DefAggregates{none, StructT{hoge}, hoge, [(int, x), (double, y)]}, DefFunc{none, int, main, [(int, argc), (PointerT{PointerT{char}}, argv)], { [DefVar{none, StructT{hoge}, st, nil}, Select{Var{st}, x} = IntL{0}, Select{Var{st}, y} = FloatL{2.0}, Call{Var{printf}, [StringL{"%d, %f\n"}, Select{Var{st}, x}, Select{Var{st}, y}]}] }}]}
ãã®ãããªãã³ãã¬ã¼ãã¯ãã¡ããå ã»ã©ã¨åæ§ã«æä½ããäºãåºæ¥ã¾ããä¸ã§ã¯Amberã®ã³ã¼ãä¸ã«åãè¾¼ã¿ã¾ããããCASTã®ã³ã¼ããæ¸ãããå¤é¨ãã¡ã¤ã«ããã¼ãºããäºãåºæ¥ã¾ãããã¨ã¯ãã¡ã¤ã«ã«ã³ã¼ããæ¸ãåºãpretty printerãå®è£ ããã°CAST -> CASTã®å¤æå¨ãåºæ¥ä¸ããã¾ããä»ã¯å®é¨çãªå®è£ ã§ãããããã¡ããã¨Cè¨èªã®ãã¼ãµãå®è£ ãã¾ãã(PEGã§ã¯æ¸ããªãã®ã§ãã¼ãµãç´ã«æ¸ãä¸ãå½¢ã«ãªãã¾ãã) ã¾ãå種æé©åãã©ã¤ãã©ãªé¢æ°ã¨ãã¦å®è£ ããäºå®ã§ãããã®ã©ã¤ãã©ãªã¯FFIã®å®è£ ãªã©ã§ä½¿ãã¾ããAmberã®æ¬¡æVMã®å®è£ ã«ãããã使ããlibcä»æ¢åã®ã©ã¤ãã©ãªã使ããããã«ããã¤ããã§ãã
ãã¼ãµã¯åã ã®æ§æè¦ç´ ãç¬ç«ããé¢æ°ã¨ãã¦çæããã¾ãã
amber:116> syntax::expr => <#Function> amber:117> syntax::stmt.domain => domain = (parser @ Parser) when *hidden* | (parser @ Parser) when *hidden* | (_ @ Parser)
å¾ã£ã¦ãé¢æ°åä½µã使ã£ã¦æ¢åã®ææ³ãæ¡å¼µããäºãåºæ¥ã¾ãã
amber:118> syntax::mystmt ::= "mystatement" "{" stmt "}" { `printf("my statement %p\n", '!$2) } => <#Function> amber:119> syntax::stmt = syntax::mystmt | syntax::stmt => <#Function> amber:120> mystatement{ puts("Hello") } my statement Apply{puts, ["Hello"]} => nil
è¨èªã®æ§æã«ä½ããã®æ¡å¼µãè¡ãå ´åããã¼ãµå ¨ä½ãä¸ã¤ã®å®ä½ã¨ãã¦ä½ããã¦ããå ´åã«ã¯ã½ã¼ã¹ã³ã¼ãã«æãå ¥ããå¿ è¦ãããã¾ããä¸ã®æ¹æ³ãªãã°ã½ã¼ã¹ã³ã¼ããæ¸ãæããã«å¤å´ããæ¡å¼µã追å ããäºãåºæ¥ã¾ãã
ãªãã¸ã§ã¯ãã·ã¹ãã
Amberã«ã¯ãããã¿ã¤ããã¼ã¹ã®ãªãã¸ã§ã¯ãã·ã¹ãã ãå®è£ ããã¦ãã¾ãã
- ãªãã¸ã§ã¯ãã«ã¯ã¹ãããã追å ããäºãåºæ¥ãã
- parentã¨ããç¹å¥ãªã¹ãããããããåç §ãããã¹ããããè¦ã¤ãããªãã£ãå ´åã«ã¯parentãè¦ã«è¡ãã
- obj.f(...)ã¨ããå½¢ã§é¢æ°ãå¼ã³åºãããå ´åãfå é¨ã§ã¯selfã«ãã£ã¦objãåç §ããäºãåºæ¥ãã
amber:121> a := 'Foo{} => Foo{} amber:122> b := 'Bar{} => Bar{} amber:123> a.f() = "self=" ++ str(self) => <#Function> amber:124> b.parent = a => Foo{} amber:125> a.f() => "self=Foo{}" amber:126> b.f() => "self=Bar{}"
self.x ã¨ããå½¢ã¯é »ç¹ã«ç»å ´ããã®ã§selfãçç¥ãã¦.xã¨æ¸ããããã«ãªã£ã¦ãã¾ãã
amber:127> a.x = 0 => 0 amber:128> a.g() = puts(.x) => <#Function> amber:129> a.g() 0 => nil
ã¾ã, ãªãã¸ã§ã¯ãã®çæã¨ã¹ãããã®è¿½å ãä¸åº¦ã«è¡ããããã« obj with { ã¹ãããã®åæå } ã¨ããæ§æãä½ãã¾ããã
amber:130> obj := 'Foo{} with { amber:130~ .x = 1 amber:130~ .y = 2 amber:130~ .f() = .x + .y amber:130~ } => Foo{} amber:131> obj => Foo{} amber:132> obj.x => 1 amber:133> obj.y => 2 amber:134> obj.f() => 3
親ã¨åãååã®é¢æ°ãæã¤å ´åãåã®é¢æ°ã親ã®é¢æ°ãé è½ãããããªå®è£ ãå¤ãã¨æãã¾ãããAmberã§ã¯è¦ªã¨åã®é¢æ°ãåä½µããæ°ããªé¢æ°ãåã«è¿½å ããã¾ããä¾ãã°ä»¥ä¸ã®ããã«ãªãã¾ãã
amber:135> .clear() => nil amber:136> a := 'Foo{} with { amber:136~ .f(x) = "parent" amber:136~ } => Foo{} amber:137> b := 'Foo{} with { amber:137~ .parent = a amber:137~ .f(0) = "child" amber:137~ } => Foo{} amber:138> b.f(1) => "parent" amber:139> b.f(0) => "child" amber:140> a.f(0) => "parent"
åä½µããããªãå ´åã«ã¯ãobj.f(...) := ã¨ããæ§æã使ããªãã§obj.fã«ç¡åé¢æ°ãä»£å ¥ããããã«æ¸ãã°ããã§ãã
ããã使ã£ã¦é¢ç½ãäºãåºæ¥ã¾ãã
amber:141> fib := 'Fib{} with { amber:141~ .f(n) = .f(n-1) + .f(n-2) amber:141~ .f(0) = 0 amber:141~ .f(1) = 1 amber:141~ } => Fib{} amber:142> fib2 := 'Fib{} with { amber:142~ .parent = fib amber:142~ .f(0) = 1 amber:142~ } => Fib{} amber:143> fib.f(20) => 6765 amber:144> fib2.f(20) => 10946
fib2ã§ã¯f(0) = 1以å¤ã¯è¦ªã®å®ç¾©ã使ã£ã¦æ°ããé¢æ°ãåæãã¦ãã¾ãã.f(n-1) + .f(n-2) ã®é¨åã§å¼ã³åºãããfã®å®ä½ãselfã«ãã£ã¦åçã«æ±ºã¾ãOpen recursionã¨ããæ§è³ªã¨Amberã®é¢æ°åä½µã®ã¡ã«ããºã ãçµåãã¦ä½¿ã£ã¦ãã¾ãããã®ããã«ã親ãä¸åæ¸ãæããã«æ©è½ãæ¡å¼µãããã¼ã¸ã§ã³ãæ°ãã«ä½ããã¨ããäºãé常ã«æ軽ã«å®ç¾åºæ¥ã¾ãã
Amberã®ã¢ã¸ã¥ã¼ã«ã¯å®ã¯é常ã®ãªãã¸ã§ã¯ãã§ããä¸ã®ä»çµã¿ãæ¨æºã©ã¤ãã©ãªã§å®è£ ããã¦ãã¾ãã.push()ã¨ããã¡ã½ããã¯ãç¾å¨ã®å¤æ°è¡¨ã®åä¾ãæ°ãã«ä½ãã¾ãã.pop()ã¯å¤æ°è¡¨ãç ´æ£ãã¦è¦ªã«æ»ãã¾ããããã«ãã£ã¦.push()ãã.pop()ã¾ã§ã®éã®å·®åã®ã¿ãç ´æ£ããã¾ãã
amber:145> x := "old version" => "old version" amber:146> .push() => nil amber:147> x := "new version" => "new version" amber:148> .pop() => nil amber:149> x => "old version"
以ä¸ã®æ§ã«Open recursionã«ãã£ã¦åã¢ã¸ã¥ã¼ã«å¤æ°ã¯å¸¸ã«ææ°ã®å¤æ°è¡¨ãåç §ãã¾ãããã®ç¹ããµãã¹ã³ã¼ããä½ãã®ã¨ã¯ç°ãªãã¾ãã
amber:150> f() := x => <#Function> amber:151> .push() => nil amber:152> x := "new version" => "new version" amber:153> f() => "new version" amber:154> .pop() => nil amber:155> f() => "old version" amber:156> { amber:156~ x := "new version" amber:156~ f() amber:156~ } => "old version"
以ä¸ã®ä¾ã¯ãä¸æçã«æ´æ°ã®ååæ¼ç®ãå ¨ã¦æçæ°ã®ç©ã«ç½®æããpopã«ãã£ã¦ãããå ã«æ»ãã¨ããä¾ã§ãã
amber:157> 1/2 => 0.5 amber:158> .push() => nil amber:159> import algebra::rational (*) => Module{rational} amber:160> 1/2 + 2/3 => 7 / 6 amber:161> s := 0 => 0 amber:162> for i in 1..100 amber:162~ s += 1/i => nil amber:163> s => 14466636279520351160221518043104131447711 / 2788815009188499086581352357412492142272 amber:164> .pop() => nil amber:165> 3/5 => 0.6
ãã®ããã«Amberã§ã¯ãªãã¸ã§ã¯ãã·ã¹ãã ããªãã¸ã§ã¯ãæåã®çºã¨ããããã¯ãããå¤æ°ã®ç®¡çã«çºã«å°å ¥ãã¦ãã¾ããä¸å¿ã以ä¸ã®ããã«åå§çãªã¯ã©ã¹ããã¬ã¤ãã¯æ¨æºã©ã¤ãã©ãªã§ç¨æãã¦ãã¾ãããã¡ãã¯ä½æ©è½ã§ãã
amber:166> class Point{x, y} => Class{Point} amber:167> p := Point.new(x = 1, y = 2) => Point{1, 2} amber:168> trait PairLike with { amber:168~ .to_pair() := (self[0], self[1]) amber:168~ } => Trait{PairLike} amber:169> Point.extend(PairLike) => Class{Point} amber:170> p.to_pair() => (1, 2)
ç´¹ä»ãã®1çµãã
ãã®ï¼ã§ã¯Amberã®ã¢ããªã±ã¼ã·ã§ã³ã¨ãã¦ã対話ã»ãã·ã§ã³ã«ããçããã³ãã¬ã¼ãããCè¨èªã®ã³ã¼ããçæããã¨ããæ°å¤è¨ç®ããã®ä¾ãç´¹ä»ãããã¨æãã¾ãã
ã·ã«ã´ã®ããªã¶ã¼ãã«ééãã話
ç¾å¨2ã«æã®çææ»å¨ç 究ã§ã¢ã¡ãªã«ã«æ¥ã¦ãã¾ããä¸äººã§ã®æµ·å¤æ»å¨ã¯åãã¦ã§ãã
ãã¦ããã®æ»å¨åæ¥ããè²´éãªçµé¨ãããã®ã§è¨é²ãæ®ãã¦ããã¾ãã
æ¥æ¬ã§ããã¥ã¼ã¹ã«ãªã£ããããã·ã«ã´ã®ããªã¶ã¼ã(ã¹ãã¼ãã²ãã³)ã«æã¾ãã¾ããã
(Chicago Tribune)
2/1, 7:50
æç°ãåºã¦Chicago O'Hare International Airport(ORD)ã«æééãã«å°çãããã¦Newark Liberty International Airport(EWR)è¡ãã«ä¹ãæããäºå®ã ã£ãã®ã§ãããæ¢ã«æ¬ èªã決ã¾ã£ã¦ãã¾ããã
ãã±ããã®æ¯æ¿ããé¡ãããã®ã§ãããå½æ¥ä¾¿ã¯å
¨ã¦æ¬ èªã«ãªããããç¿æ¥ã®ä¾¿ã«å¤ãã¦ãããã¾ããã
ã¨ããããã§ã·ã«ã´æ³ã決å®ãèªåã¯ä»¥ä¸ã®ããã«ãã¦å®¿ã確ä¿ãããã¨ãã§ãã¾ããã
- ã¾ããè·å¡ã«ç¸è«ããã¨Airport Accommodationã¨æ¸ããããã³ã¯è²ã®ãã±ãã(åçæ®ãå¿ãã)ããããããããã§ããã«ã®é¨å±ãå®ãåããã¨ããã
- ããã¼åãä»ãã®é»è©±ããäºç´ã»ã³ã¿ã¼ã«é»è©±(#7)ãã¾ã空港åãèãããããã³ã¯ã®ãã±ããã¯ããã£ã¦ããï¼ã¨èãããã次ã«ããã«ã®åè£ã¨éé¡ãè¨ã£ã¦ãããã®ã§é¸ã¶(èªåã¯$60ã®Hilton Garden Innãé¸ãã )ã次ã«ååãèããããç¸æã¯æ¥æ¬åã®ã¹ãã«ãåãããªãã®ã§ãN,A,K,A,M,U,R,Aã¨ä¸æåãã¤ãããæå¾ã«ããã³ã¯ã®ãã±ããã«ããã«åãéé¡ãäºç´çªå·ãè¨å ¥ããããã«è¨ãããã
- ããã«ã«ç§»åãããã¿ã¼ããã«ã®å ¥ãå£åã«ã·ã£ãã«ãã¹ä¹ãå ´ãããã®ã§ãæ³ã¾ãããã«ã®ååãæ¸ãã¦ãããã¹ã«ä¹ãã大ä½30åééãããã§èµ°ã£ã¦ããã
- ããã«ã«çããããã³ã¯ã®ãã±ããã¨ã¯ã¬ã¸ããã«ã¼ããåä»ã«æ¸¡ãã
ããã«ã«ç§»åããã¾ã§ã®éãã¹ã®é転æãããããæãã¦ããã¾ãããã¾ããä»æ©ã¯éå»ã«ç¡ããããã®ç©éª(50ã»ã³ã)ãäºæ³ããã¦ããã¨ãããã¨ãææ¥ã®ç©ºæ¸¯ã¯å¤åééãããã ãããã¨ãããã¨ãæ°æ¥ã¯åããªãã ãããã¨ãããã¨ã
2/1, 9:30é
ããã«ã§ã¯Free WIFIã ã£ãã®ã§å®¶æçã«é£çµ¡ãã天æ°äºå ±ããã©ã¤ãã®ç¶æ³ãªã©ããã§ãã¯ãã¾ããã
ãããããã¦ããã¨ãæ¼éããããã«çªç¶åé»ãããããéããªããªãã¾ãããããã³ãã«è¡ãã¨äººããããããã¦ãã³ã¼ãã¼ã飲ãã§è©±ããã¦ãã¾ãããèªåã¯æå·®ã¼ãããã£ã¦ç ãã£ãã®ã§ãæ¯å¸ãï¼ã¤ããã£ã¦é¨å±å¸°ã£ã¦å¯ã¾ããã
2/1, 18:00é
èµ·ãããéªãæ¿ãããªã£ã¦ã¾ããã
åé»ã¯ã¾ã ç¶ãã¦ãã¾ããã
ãè
¹ããããã®ã§å¤é£ãäºåé»æºããªããã§èª¿çãã¦ããããããæçãåºã¦ããã®ã«æéããããã¨ãã説æã40åãããå¾
ã£ãã¨æãã¾ãã
Shrimp Scampiãé£ã¹ã¦ããæã«ã¬ã¹ãã©ã³ã®ç
§æãå
¨é¨è½ã¡ã¾ãããé£ã®ããã¼ã¯ã¾ã ç
§æãçãã¦ããã®ã§ãã»ãã®ãæããã¨ãããããã§ãããåé»ã®çºã¯ã¬ã¸ããã«ã¼ãã使ããªãã®ã§ãé£äºä»£ã¯é¨å±ä»£ã«å¾ã§ä»ããã¨ãã説æãããã¾ããã
ã¤ã³ã¿ã¼ãããåç·ãçãã¦ããªãã®ã§èªåã¯ç¶æ³ãåãããªãã£ãã®ã§ãããæºå¸¯é»è©±ã§æ
å ±åéãã¦ããä¸å½ç³»ã¢ã¡ãªã«äººã®äººã«ããããæãã¦ãããã¾ãããããããä¸ä½ã¯å
¨é¨åé»ãã¦ãã¾ã£ã¦ãã¦ä»æ¥ä¸ã«ã¯å¾©æ§ããè¦è¾¼ã¿ããªãã¨ãããã¨ã§ããã
ããããã空港å¨è¾ºã§ã¯2ã¤ã®ããã«ã ããé»æ°ç³»çµ±ãç¡äºã ã¨ããäºãæãã¦ãããã¾ããããã¡ãã移åæ段ã¯ããã¾ããã
ä½ãã§ããªãã®ã§é¨å±ã«æ»ãã¾ããããæå·®ã¼ãã§ç ããªãã®ã§ã³ã¼ãã£ã³ã°ããããªã©ãé»æºã¯æ»ãã§ã¾ããããåºçºåã«äºåããããªã¼ãç¨æãã¦ããã®ãã©ããã¼ã§ããã
2/1, 22:00é
çªç¶ç«ç½è¦å ±ããªãã¾ãããé¨å±ã®ã¹ãã¼ã«ã¼ãã大é³éã§ãç«ç½å ±ç¥æ©ãåå¿ãã¾ããã確èªä¸ãªã®ã§å¾
ã£ã¦ä¸ãã(Please hold on)ãã¨æµããå°ãããã¨ããã®ä»è¿ã§ç«ç½ãçºçãã¾ãããã¨ã¬ãã¼ã¿ã¯ä½¿ããªãã§é常é段ããç´ã¡ã«å¤ã«åºã¦ãæ示ã«å¾ã£ã¦ä¸ããããã¿ãããªæãã®æ¾éã«å¤ããã¾ãããã¨ããããã§æ
ã¦ã¦é¿é£ãç®ã®åãæ©ãã¦ã人ã¯è£¸è¶³ãé常é段ã¯é»æ°ãã¤ãã¦ã¾ããã
ä¸éã®é常å£ã¯å¤ããéªã§ãµããã£ã¦ã¦éããªãããã¨ããããããã¼æ¹åã«ç§»åãããã¼ã«ã¯äººããããããããã¦ç´ãã«æ¶é²è»ãæ¥ã¾ãããçµå±ç«äºã§ã¯ãªãã¦ãé»æ°ç³»çµ±ã®æ
éã«ããè¦å ±æ©ã®èª¤ä½åã¿ããã§ãããæã¾ã§è¨4åç«ç½è¦å ±ãããã¾ããã
ãããªéªãªã®ã«æ¶é²è»ãæ¥ããã®ã¯å¤§åã®é¤éªè»ãå¤éãä½æ¥ãã¦ããããã®ããã§ãã
åçã®å ´æã¯é¤éªè»ãã¬ã½ãªã³ãè£çµ¦ããå ´æã®ããã§ãã
ããã¯èªåã®é¨å±ããæ®ã£ãåçã
2/2, 9:00é
å¤ä¸ã«æ¯ã¹ãã¨ééªãæ¸ã£ã¦ãã¾ãããåçã«ç§»ã£ã¦ããã®ã¯ããã«ã®äººã§å¥¥ã«è¦ããã·ã£ãã«ãã¹ã移åããããã¨ãã¦ãã¾ããã
ããã¼ã§ã³ã¼ãã¼ã飲ãã§æã¾ã£ã¦ããã¨ãã·ã£ãã«ãã¹ãå
¥ãå£ã¾ã§æ¥ã¦å¾æ¥å¡ã®äººãã¢ãã¦ã³ã¹ããæ¨æ©ã¯åé»ã§ä¸ä¾¿ãããã¦ç³ã訳ããã¾ããã§ãããé£äºä»£ãé¤ãã¦æ¨æ¥ã®é¨å±ä»£ã¯é ãã¾ãããããããå¥ã®é»æ°ç³»çµ±ãç¡äºã§æé£ãåãäºãåºæ¥ãããã«(確ã$99ã®ã¨$85ã®2ã¤åè£ããã£ã)ã¸ãã¹ãåºãã¾ãããã¨ãããããªæãã®å
容ã ã£ãã¨æãã¾ããHilton Garden Innã§ã¯æé£ã®ä»å
¥ããåºæ¥ã¦ããªãã¿ããã§ããã
èªåã¯$99ã®æ¹(Embassy Suites)ãé¸ãã§ã·ã£ãã«ãã¹ã«ä¹ãã¾ããã移åä¸ã¯çã£ç½ã§ä½ãè¦ãããè·¯è©ã®éªãåããªããèµ°ããããªæãã§ãããéä¸éªã«åã¾ã£ã¦ããè»(ãã¡ãã人ã¯ä¹ã£ã¦ããªã)ã沢山ããã¾ããã
(é·ãã®ã§ç¶ãã¯å¾ã§æ¸ã)
ãæ«å°¾æé©åããæ£ããç解ãã
以ä¸ã®è¨äºã§PythonãRubyã®æ«å°¾å帰é¢æ°ãã«ã¼ãã«å¤æããææ³ããæ«å°¾å帰æé©åãããæ«å°¾å¼ã³åºãæé©åãã¨ãã¦ç´¹ä»ããã¦ããã®ã§ããããããã®ç¨èªã使ãã®ã¯ééãã§ãã
ç´¹ä»ããã¦ããææ³(åçæç¸ãå©ç¨ãã¦å¶å¾¡ããã¼ãå¤å½¢ããææ³)èªä½ã¯å¤§å¤é¢ç½ãã§ããã
Pythonで末尾再帰最適化をする。
Rubyで末尾再帰最適化をする。
åèæç®ã¨ãã¦ä»¥ä¸ãæãã¦ããã¾ãã
William D. Clinger "Proper Tail Recursion and Space Efficiency"
ã¡ããã¨èªã¿ç´ãã¦ããªãã®ã§ã以ä¸ã®èª¬æã«ééããããããç¥ãã¾ããããã®å ´åã¯ãææãé¡ããã¾ãã
ã¾ããæ«å°¾å¼ã³åºã(Tail Call)ãã¯é¢æ°ã®ä¸çªæå¾ã®å¼(æ«å°¾å¼)ã§ãã£ã¦ãé¢æ°å¼ã³åºãã§ãããã®ãæãã¾ãã
void foo() { bar(); baz(); /* æ«å°¾å¼ã³åºã */ }
æ«å°¾å¼ã³åºãã¯å帰å¼ã³åºãã§ãªãã¦ãè¯ãã®ã§ãæ¬æ¥ã¯æ«å°¾å帰ããåºãæ¦å¿µã§ããããããæ«å°¾æé©åãå¿
è¦ã«ãªãã®ã¯ã»ã¨ãã©ã®å ´åå帰é¢æ°ãªã®ã§ã[è¨æ£]é¢æ°å¼ã³åºããå帰ãããå¦ããå¤æããäºã¯å°é£ã§ãã(ã³ã¼ã«ã°ã©ãã®æ§ç¯ãé£ãã)ãããæ«å°¾å¼ã³åºããç¡æ¡ä»¶ã§æ«å°¾å帰ã¨å¼ã¶ãã¨ãããããã§ãã
é¢æ°ãå¼ã³åºãéã«ã¯è²ã ãªç¨éã§ã¡ã¢ãªç¢ºä¿ãçºçãã¾ãã
- æ»ãå ã¢ãã¬ã¹ãã©ããã«ç©ã
- é¢æ°å¼æ°ã確ä¿ãã
- å¼ã³åºãå ã®ãã¼ã«ã«å¤æ°ãéé¿ãã
- å¼ã³åºãããé¢æ°ã®ãã¼ã«ã«å¤æ°ã確ä¿ãã
- ã¯ãã¼ã¸ã£ã®èªç±å¤æ°ã確ä¿ãã
çã§ãã
æ«å°¾å¼ã³åºãã®å ´åã¯ããããé¤å»ã§ããããã§ãããã©ãã»ã©å¹ççãªå®è£
ã«ãªã£ã¦ããããã£ã¦ããã¤ãã®ã¯ã©ã¹ã«åé¡ããã¾ãã
Improper Tail Recursionã¨Proper Tail Recursion
æ«å°¾å¼ã³åºãæã«æ»ãå
ã®ç¶ç¶ã渡ããããªå®è£
ãImproper(誤ã£ã) Tail Recursionãçæããªãå®è£
ãProper(æ£ãã) Tail Recursionã¨è¨ãã¾ãããæ»ãå
ã®ç¶ç¶ãçæãã¦æ¸¡ããã¨ããã®ã¯ã大æµã®å®è£
ã§ã¯ç¾å¨ã®ç°å¢(ãã¼ã«ã«å¤æ°ç)ãä¿åããæ»ãå
ã¢ãã¬ã¹ãã¹ã¿ãã¯ã«ç©ã¿ãé¢æ°ãã³ã¼ã«ãã¦ãããªã¿ã¼ã³ãããããªãã®ãæãã¾ãã
Improper Tail Recursionã§ã¯ãç°å¢ã®ç¢ºä¿ãªã©ãããã工夫ãã¦0ã«ãã¦ãæ»ãã¢ãã¬ã¹ã¯é¤å»ã§ããªãã®ã§å¿
ãã¡ã¢ãªãå¢å ãããã¤ãã¡ã¢ãªã足ããªããªãã¾ãã
ä¸æ¹ã®Proper Tail Recursionã¯ç¾å¨ã®ç°å¢ãç ´æ£ããé¢æ°ã³ã¼ã«ã®ä»£ããã«ãã ã®ã¸ã£ã³ããè¡ããããªå®è£
ãæãã¾ãã
ãã®å ´åãä¸åã®ã¡ã¢ãªã®å¢å ãé²ããã¨ãã§ãã¾ãã
ããã«ç´°ããã¯ã©ã¹åãã«ã¤ãã¦ãããã£ã±ã«èª¬æãã¾ãã
Improper Tail Recursionã®ã¯ã©ã¹
- S-Stack
- ç°å¢ã®ä¸é¨ãã¹ã¿ãã¯ä¸ã«ç´æ¥ç¢ºä¿ããå®è£ ã
- S-GC
- ç°å¢ããã¼ãã«ç¢ºä¿ãããã¤ã³ã¿ä¸ã¤ãä¿åããå®è£ ããã®å ´åé¢æ°ã³ã¼ã«ããæ»ããã¨ããæ»ãã ãã¼ã¿ã¯GCã«ãã解æ¾ã§ããã®ã§ãS-Stackããã¡ã¢ãªå¹çãè¯ãã¯ã©ã¹ã§ãã
Proper Tail Recursionã®ã¯ã©ã¹
- S-Tail
- ä¸ã§æ¸ããProper Tail Recursionã®æä½éã®æ¡ä»¶ãæºãããå®è£ ã
- S-Evlis
- S-Tailã®æ¡ä»¶ã«å ãæ«å°¾å¼ã³åºããã¾ããã ç°å¢ã®éé¿ãé¤å»ããå®è£ ããã¼ãã«éé¿ãããç°å¢ã¯äºåº¦ã¨ã¢ã¯ã»ã¹ãããªãã®ã§ãé¤å»ã§ãã¾ãã
- S-Free
- S-Tailã®æ¡ä»¶ã«å ãã¯ãã¼ã¸ã£å¤æãç¨ããå®è£ ãç°å¢ã®éé¿ãæå°éã«ãªãã¾ãã
- S-SFS (Safe for Space)
- S-Freeã«å ããæ¡ä»¶åå²ãªã©ã§ãå¤æ°ã®çå解æã使ãæ¹æ³ãç°å¢ã®éé¿ãããã«æ¸ãã¾ãã
ãã¦ãä¸è¬çã«ã¯æ«å°¾å¼ã³åºããProper Tail Recursionã§å®è£
ããããã¨ãæ«å°¾æé©åãããã¨è¨ãã¾ãã
ä¸ã®PythonãRubyã®ä¾ã¯é¢æ°ã³ã¼ã«ãé¤å»ãã¦ããããã§ã¯ãªãã®ã§æ«å°¾æé©åã«ã¯è©²å½ãã¾ãããé¢æ°ã®å¼ã³åºãé¢ä¿ãæ¸ãæããå¥ç¨®ã®å¤æã«ãªãã¾ãã
å®éããã®æ¹æ³ã§ãæ«å°¾å帰é¢æ°ã§ããã°ã¹ã¿ãã¯ã®å¢å ãé²ãã¦ããããã§ãããf(),g(),h(),..ã¨ç°ãªãé¢æ°ã次ã
ã¨æ«å°¾å¼ã³åºããããããªå ´åã«ã¯ã¹ã¿ãã¯ã®å¢å ãæããäºã¯ã§ããªããªã©ã®ç¹ã§æ«å°¾æé©åã¨ã¯ç°ãªã£ã¦ãã¾ãã
Project Euler (74 ã 80) ãã¿ã´ã©ã¹æ°ãäºè§æ°å®çããããã¸ã«ã«ã½ã¼ããªã©
ä»æ¥ã¯80ã¾ã§ããã®ã¨ãããæ°å¦ã使ãåé¡ã沢山ã§é¢ç½ãã§ããã
ãã¿ã´ã©ã¹æ°ã¨ããã³ããæ¨ Problem75
ç°¡åã«ã¯
1,500,000以ä¸ã®Lã§
a^2 + b^2 = c^2 ã㤠a + b + c = L
ãæºããèªç¶æ°a,b,cã®çµãã¡ããã©ä¸çµã¨ãªããããªLã®åæ°ãæ±ãã
ã¨ããåé¡ã§ããa^2 + b^2 = c^2ãæºããèªç¶æ°(a,b,c)ããã¿ã´ã©ã¹æ°ã¨è¨ãã¾ããã¾ãããã®æ¹ç¨å¼ããã¿ã´ã©ã¹æ¹ç¨å¼ã¨è¨ãã¾ããããã«æ¹ç¨å¼ãªã©ã¨åãããã£ãªãã¡ã³ãã¹æ¹ç¨å¼ã®ä¸ç¨®ã§ãã
(a,b,c)ããã¿ã´ã©ã¹æ°ã®ækãèªç¶æ°ã¨ãã¦(ka,kb,kc)ããã¿ã´ã©ã¹æ°ãªã®ã§ã(a,b,c)ãäºãã«ç´ ã§ãããã®ã«ã¤ãã¦èããã°è¯ãã§ãããããåå§ãã¿ã´ã©ã¹æ°ã¨ããã¾ãã
ãã¦ãåå§ãã¿ã´ã©ã¹æ°ã¯ãã®çææ¹æ³ãç¥ããã¦ãã¦
m > n ã㤠m,nã¯äºãã«ç´ ã㤠çæ¹ãå¶æ°ã®ã¨ã(m^2-n^2,2mn,m^2+n^2)ã¯åå§ãã¿ã´ã©ã¹æ°
ã¨ãªãã¾ãã
ãããåæããæã«åä»ãªã®ããm,nãäºãã«ç´ ãã®æ¡ä»¶ã§ãããããã§Problem 71, 73ã§ã使ã£ãブロコット木ãå½¹ã«ç«ã¡ã¾ãã
ããã³ããæ¨ã使ãã¨æ¢ç´åæ°ãé«éã«åæããäºãã§ããããã§ããããã®ã¨ãååã¨åæ¯ãå¿
ãäºãã«ç´ ã«ãªã£ã¦ããæ§è³ªã使ãã¾ãã
L = 1500000 $count = {} # 解ã®åæ° def dfs(la,lb,ra,rb) # naã¨nbã¯äºãã«ç´ na = la + ra nb = lb + rb c = 0 if (na+nb)%2 == 1 l = 2*(na+nb)*nb return if l > L # åå§ãã¿ã´ã©ã¹æ°ã®åæ°ãã«ã¦ã³ã (1..L/l).each do |k| $count[k*l] || $count[k*l] = 0 $count[k*l] += 1 end end dfs(la,lb,na,nb) dfs(na,nb,ra,rb) end dfs(0,1,1,1) count = 0 $count.each_value {|v| count += 1 if v == 1} puts count
å®è¡æéã¯1.11sã§ããã
æ´æ°åå²ãäºè§æ°å®ç(Problem 76, 77, 78)
ãã®3åã¯整数分割ã«é¢ããåé¡ã§ããæ´æ°åå²ã¨ã¯æ´æ°nãèªç¶æ°ã®åã§è¡¨ãå ´åã®æ°ã§ããä¾ãã°n=5ã®å ´åã¯ä»¥ä¸ã®7éããããã¾ãã
5
4 + 1
3 + 2
3 + 1 + 1
2 + 2 + 1
2 + 1 + 1 + 1
1 + 1 + 1 + 1 + 1
ã¨ã©ã®ã¤ã¾ãããã¯ã硬貨æ¯æãåé¡ã¨åãã§ãã5åã1åçã2åçã3åçã4åçã5åçã®çµã¿åããã§æ¯æãæ¹æ³ã¯7éãã¨ãã訳ã§ããå¾ã£ã¦以前書いた方法ã¨å ¨ãåãã¢ã«ã´ãªãºã ã§è¨ç®ã§ãã¾ãã
Problem 76: 100ã2ã¤ä»¥ä¸ã®èªç¶æ°ã®åã§è¡¨ãæ¹æ³ã®æ°ãæ±ãã
100åã1,2,...,99åçã§è¡¨ãæ¹æ³ãçãã§ãããã£ã¦ç¡¬è²¨æ¯æãåé¡ã¨åã漸åå¼ã使ãã¨ä»¥ä¸ã®ããã«ãªãã¾ããa[k][n]ã¯nãk以ä¸ã®åã§è¡¨ãæ¹æ³ã®æ°ã§ãã
class Array def [](i) i < 0 ? 0 : at(i) end end N = 100 a = (0..N).collect { [] } (0..N).each do |n| t = a[1][n] = a[1][n-1] + ((n == 0) ? 1 : 0) (2..N).each do |k| t = a[k][n] = a[k][n-k] + t end end puts a[99][100]
å®è¡æéã¯0.01sãããã§ãã
Problem 77: ç´ æ°ã®ã¿ã®åã§è¡¨ãæ¹æ³ã5000éã以ä¸ã¨ãªãæåã®æ°ã¯ä½ãï¼
2,3,5,7,11,13,..å硬貨ã§æ¯æãæ¹æ³ã®æ°ã¨èããã°å ¨ãåãã§ããéé¡ã®ä¸éã¯é©å½ã«æ±ºããå¿ è¦ãããã¾ãã
class Array def [](i) i < 0 ? 0 : at(i) end end #ä¸éãé©å½ã«æ±ºãã N = 100 # ç´ æ°ã®ãµãããã¤ãã£ã¦ãã sieve = [] 2.upto(N) do |p| next if sieve[p] (2*p).step(N,p) {|k| sieve[k] = true} end a = (0..N).collect { [] } (0..N).each do |n| t = a[2][n] = a[2][n-2] + ((n == 0) ? 1 : 0) (3..N).each do |k| next if sieve[k] # kãåææ°ã®æãã¹ããã t = a[k][n] = a[k][n-k] + t if a[k][n] > 5000 puts n exit end end end
å®è¡æéã¯0.01sã§ãã
ãã®èãæ¹ã¯åãããããã¦è¯ãã®ã§ãããã¡ã¢ãªãå¤ã使ç¨ããã¨ããæ¬ ç¹ãããã¾ããããã§å½¹ã«ç«ã¤ã®ãオイラーの五角数定理ã§ããããã¯
ã¨ãããã®ã§ãã
nã®æ´æ°åå²ã®æ°p(n)ã®æ¯é¢æ°ã¯
ã¨ãªãã®ã§ãäºè§æ°å®çã使ãã°
ã¨ãªãã¾ãããããå±éãã¦ä¿æ°æ¯è¼ãããã°ãåå²æ°ã®æ¼¸åå¼ãä½ãã¾ãã
Problem 78ã¯ãã®æ¹æ³ã§è§£ãã¾ãããã¾ã è¨ç®æéãæãã£ã¦ããã®ã§ãã£ã¨è¯ãæ¹æ³ãããããããã¾ããã
Problem 78: åå²æ°ãåãã¦1,000,000ã®åæ°ã¨ãªãæ´æ°ãæ±ãã
p = [1] 1.upto(1/0.0) do |n| p[n] = 0 1.upto(1/0.0) do |k| if (m = n - k*(3*k+1)/2) >= 0 p[n] += p[m] * (2*(k%2)-1) end if (m = n - k*(3*k-1)/2) >= 0 p[n] += p[m] * (2*(k%2)-1) else break end end if p[n] % 1000_000 == 0 puts n exit end end
å®è¡æéã¯41.5sã§ããã
ãããã¸ã«ã«ã½ã¼ã(Problem 79)
ããé·ãä¸æã®æ°åãããããã®é·ã3ã®é¨åæ°åã
319
680
180
690
129
...(ç¥)
ã¨ãªãã¨ãããã¨ã®æ°åã¨ãã¦å¯è½ãªç©ã§æãçãç©ãæ±ãã
ããã¯ä»®ã«ãã¨ã®æ°åã«åãæ°ãè¤æ°ååºç¾ããªããªããトポロジカルソートã®åé¡ã§ãã
ããã§ãã¾ãGraphvizã§ã°ã©ããæãã¦ã¿ã¾ãããDOTè¨èªã§è¨è¿°ãã¾ãã
digraph problem79 { 3 -> 1 -> 9 6 -> 8 -> 0 1 -> 8 -> 0 6 -> 9 -> 0 1 -> 2 -> 9 ... }
ãã®çµµããçãã¯ä¸ç®çç¶ã§ããã
ä¸å¿Rubyã§ãããã¸ã«ã«ã½ã¼ããè¡ãã³ã¼ããè¼ãã¦ããã¾ãããããã°ã©ãã«ã«ã¼ããããã°ç¡éã«ã¼ãã«ãªã£ã¦ãã¾ãé常ã«éãªã³ã¼ãã§ãã..ã
file = open("problem79-keylog.txt") # ã°ã©ããä½ã $graph = (0..9).collect {Array.new(10,false)} $used = [] while line = file.gets x, y, z = line.split(//).map {|v| v.to_i} $used[x] = $used[y] = $used[z] = true $graph[x][y] = $graph[y][z] = true end # ãããã¸ã«ã«ã½ã¼ã $visited = [] def visit(v) return if $visited[v] $visited[v] = true 0.upto(9).each do |s| next if not $used[s] or not $graph[s][v] visit(s) end puts v end 0.upto(9).each {|v| $used[v] && visit(v)}
å®è¡æéã¯0.01sã
æ´æ°æ¢ç´¢ã«ç´ã(Problem 80)
å¹³æ¹æ°ã§ãªã100æªæºã®nã«ã¤ãã¦
ânã®æå100æ¡ã®æ°ã®å
ã®åãæ±ãã
開平法ã¨ããæãããã¾ããå®è£
ãé¢åã§ããä»åã¯100æ¡ã¨åãã£ã¦ããã®ã§ããã£ã¨ç°¡åãªæ´æ°ã®æ¢ç´¢åé¡ã«ç´ãã¡ããäºãã§ãã¾ããã¤ã¾ãnã100æªæºãªãã°
ãæºããæ´æ°kããã®æåã®100æ¡åã§ããã¨ãããã¨ã§ã以ä¸ã®æ§ã«è§£ãã¦ã¿ã¾ããã
sum = 0 2.upto(99) do |a| next if Math.sqrt(a).ceil**2 == a # äºåæ¢ç´¢ n = a*10**198 l = 10**99 r = (a+1)*10**99 while r - l > 1 t = (r+l)/2 t**2 - n > 0 ? r = t : l = t end # æ¡ã®åãåã while l > 0 sum += l%10 l /= 10 end end puts sum
å®è¡æéã¯0.26sã§ããã
Project Euler(51 ã 73) ããã³ããæ¨ãªã©
ä¹
ã
ã«Project Eulerããã¾ãããã¾ã rowlã¯ä½¿ãã段éã«ãªãã®ã§ãRubyã¤ãã£ã¦ã¾ãã
ãã®ãããããæ°è«ã®åé¡ãããããåºã¦ãã¦é¢ç½ãã£ãã§ãã
ãºã«æ¹ç¨å¼(Problem 66)
ç°¡åã«ã¯
Dãå¹³æ¹æ°ã§ãªãæ´æ°ã®æ
x^2 - Dy^2 = 1
ã®æ´æ°è§£ãæ±ãã
ã¨ããåé¡ãããã¯ãºã«æ¹ç¨å¼ã¨ãã£ã¦ããã£ãªãã¡ã³ãã¹æ¹ç¨å¼ã®ä¸ç¨®ã§ãã
以ä¸ã®ãã¼ã¸ã«è©³ããçè«ã¨è§£æ³ãç´¹ä»ããã¦ãã¾ããé£åæ°å±éã使ãã¾ãã
http://aozoragakuen.sakura.ne.jp/suuron/suuron.html
ä½è«ã§ããããã£ãªãã¡ã³ãã¹æ¹ç¨å¼(ç¹ã«ããºã¼æ¹ç¨å¼ a x + b y = d)ã¯ã³ã³ãã¤ã©ã®æç§æ¸ã«ãåºã¦ãã¾ãã¦ããã®é¢ä¿ã§ç§ã¯åãããºã«æ¹ç¨å¼ã®äºãç¥ã£ã¦ãã¾ããã
äºã¤ã®é
åã¢ã¯ã»ã¹a[p*i+q]ã¨b[r*j+s]ãåãå ´æãåç
§ãããã©ããã¯
a + sizeof(a[0]) * (p * i + q) == b + sizeof(b[0]) * (r * j + s)
ã解ãæã¤ãã©ããã§æ±ºã¾ãã¾ããããã¯i,jãå¤æ°ã¨ããããºã¼æ¹ç¨å¼ã«ãªã£ã¦ãã¾ãããã®è§£ã調ã¹ãäºã§ã«ã¼ãã®ä¸¦åæ§æ¤æ»ãªã©ãåºæ¥ã¾ãã
ãªã¤ã©ã¼ã®ãã¼ãã£ã¨ã³ãé¢æ°(Problem 69, 70)
ãªã¤ã©ã¼ã®ãã¼ãã£ã¨ã³ãé¢æ°Ï(n)ã¨ã¯nã¨äºãã«ç´ ãªn以ä¸ã®èªç¶æ°ã®æ°ã¨ãã¦å®ç¾©ããã¦ãã¾ãã
ããã¯nã®ç´ å æ°å解ã
ã¨ãªãã¨ãã
ãæºããã¾ããnã®ç´ å æ°å解ã¯é常ã«éãã§ãããããã¼ãã£ã¨ã³ãé¢æ°ã«é¢ããåé¡ã¯
- ç´ æ°ã®ãªã¹ãã®ä¸ã§æ¢ç´¢ãã
- ã¨ã©ãã¹ããã¹ã®ç¯©ã§è¨ç®
ã¨ãã£ãæ¹æ³ãåããã¨ã«ãªãã¨æãã¾ããä¾ãã°å¾è ã«é¢ãã¦ã¯ä»¥ä¸ã®ãããªã³ã¼ãã§2ãNã«ã¤ãã¦é¢æ°ã®å¤ãæ±ããäºãåºæ¥ã¾ãã
phi = (0..N).to_a 2.upto(N) do |n| if phi[n] == n # n is a prime number n.step(N, n) {|p| phi[p] = phi[p]*(n-1)/n} end end
ãã¡ã¬ã¤æ°åãããã³ããæ¨(Problem 71,72,73)
ãã®3åã¯ãã¡ã¬ã¤æ°åã«ã¤ãã¦ã®åé¡ã§ãã
ファレイ数列ã¨ããã®ã¯0以ä¸1以ä¸ã®æ¢ç´ãªåæ°ã並ã¹ããã®ã¨ãã¦å®ç¾©ããã¾ãã
ä¾ãã°åæ¯ã8以ä¸ã®æã¯
F8 = 0/1, 1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8, 1/1
ã¨ãªãã¾ãã
ãã¡ã¬ã¤æ°åã®é·ã
Problem 72ã¯ãã¡ã¬ã¤æ°åã®é·ããæ±ããåé¡ã§ãããããã¯ãã¼ãã£ã¨ã³ãé¢æ°ãç¨ãã¦
ã¨è¡¨ãã¾ããåæ¯ãkã§ããæ¢ç´ãª1æªæºã®åæ°ã¯ãkã¨äºãã«çãªk以ä¸ã®èªç¶æ°ã®æ°ã¨ä¸è´ããã®ã§ãããæç«ãã¾ãã
ããã³ããæ¨
Problem 71ã¨73ã¯ãã¡ã¬ã¤æ°åã®ä¸é¨ã ããèããåé¡ã§ãããããããåé¡ã§ã¯ããã³ããæ¨(Stern Brocot tree)ã便å©ã§ãã
ããã³ããæ¨ã¨ããã®ã¯
æ¢ç´ãªåæ°ã®ååå士ãåæ¯å士ãå ããäºãç¹°ãè¿ãã¦ä½ãããæ¨ã§å³ã®ããã«ãªãã¾ã(wikipediaããå¼ç¨)ã
ãã®ããã³ããæ¨ã¯
- çæãããåæ°ã¯å¿ ãæ¢ç´ã«ãªã£ã¦ãã
- å ¨ã¦ã®åæ°ãç¶²ç¾ ãã
ã¨ããé常ã«è¯ãæ§è³ªãæã£ã¦ãã¾ããåæ¯ååã®ç´åã®åé¡ãèããªãã¦è¯ãã®ã§ãæ¢ç´åæ°ã«é¢ããæ¢ç´¢åé¡ãé«éã«è§£ãã¾ãã
Problem 71: åæ¯ã1,000,000以ä¸ã®åæ°ã§3/7ã®æªæºã®æ大ã®ç©ã¯ä½ãï¼
3/7ãæãåºéã§ããã³ããæ¨ã辿ã£ã¦è¡ãã°è¯ãã§ãã
la, lb = 0, 1 ra, rb = 1, 2 while true ma, mb = la + ra, lb + rb if 7*ma < 3*mb if mb > 1000000 puts "#{la}/#{lb}" exit end la, lb = ma, mb else ra, rb = ma, mb end end
å®è¡æéã¯0.02sãããã§ãã
Problem 73: åæ¯ã12,000以ä¸ã®åæ°ã§1/2ã¨1/3ã®éã®æ°ã¯ä½åãï¼
æ¨ã®ãã¼ãæ°ãæ·±ãåªå æ¢ç´¢ã§æ±ããã ããã¾ããååã®æ°åã¯èããå¿ è¦ãªãã§ãã
def dfs(l, r) m = l + r return 0 if m > 12000 dfs(l, m) + dfs(m, r) + 1 end puts dfs(3, 2)
å®è¡æéã¯1.83sãããã§ãã
ããã辺ã®è©±ã¯Knuthã®æ¬ã«æ¸ãã¦ãã£ãã¨æãã¾ãã
- ä½è : ããã«ãã»L.ã°ã¬ã¢ã ,ãªã¼ã¬ã³ãã¿ã·ã¥ãã¯,ããã«ãã»E.ã¯ãã¼ã¹,Ronald L. Graham,Oren Patashnik,Donald E. Knuth,ææ²¢èª ,è©ééä¹,å®æéæ,ç³çæ¸
- åºç社/ã¡ã¼ã«ã¼: å ±ç«åºç
- çºå£²æ¥: 1993/08
- ã¡ãã£ã¢: åè¡æ¬
- è³¼å ¥: 5人 ã¯ãªãã¯: 224å
- ãã®ååãå«ãããã° (38件) ãè¦ã
rowlã®éçºãå§ãã¦ï¼å¹´ãçµã¡ã¾ãã
1å¹´åã®ä»æ¥ãã¢ã»ã³ããªã§æ°åè¡ã®echoããã°ã©ã ãä½æãã¾ããã
ãããå¾ã
ã«è²ã¦ã¦ãä»æ¥ã§ã¯ã½ã¼ã¹ã³ã¼ãè¡æ°ããã¼ã¿ã«ã§1ä¸5åè¡ãè¶
ãã¦ãã¾ããã
ï¼å¹´ã§ãã£ãããã ããã¨ããæ°ãããªãããªãã§ããã趣å³ããã°ã©ã ã«ãã¦ã¯ãããªãã«é²ãã ã®ããªã¨æãã¾ãã
å½åã®è¨ç»éãã¢ã»ã³ããªè¨èªä»¥å¤ã®æ¢åè¨èªã¯å®è£
ã«ä½¿ç¨ãã¦ãã¾ããã
ããã¾ã§ã®ææãã¾ã¨ãã¾ãã
- ã³ã³ãã¤ã©ã®å®è£ ã¯ç¬¬ï¼ä¸ä»£ã¾ã§çµäºããç¾å¨ç¬¬ï¼ä¸ä»£ã®å®è£ ãéå§ãã¦ãã¾ãã
- ã¹ã¿ãã¯ãã·ã³åã®VMãåä½ãã¦ãã¾ãã
- ã³ãã¼GC(Mostly Copying-GC)ãåä½ãã¦ãã¾ãã
- (ãã¤ãã³ã¼ãã®)JITã¢ã»ã³ãã©ãåä½ãã¦ãã¾ãã
- ãã¤ãã³ã¼ãã®ãªã³ã«ãä½æãã¾ãããåå²ã³ã³ãã¤ã«ãå¯è½ã§ãã
- ãã¤ãã³ã¼ãã®ãã£ã¹ã¢ã»ã³ãã©ãä½æãã¾ããã
- 第ï¼ä¸ä»£rowl
- ã¬ããµã»ãã¼ãµãä½æãã¾ãããæ¼ç®ååªå é ä½æ³ãã¼ã¹ã®ãã¼ãµãæ¡ç¨ãã¾ããã
- Ïå¼ãã¼ã¹ã®æ£è¦åãããæ§ææ¨è¡¨ç¾ãæ¡ç¨ãã¾ããã
- ãã¿ã¼ã³ãããã³ã°ãä¸é¨å®è£ ãã¾ãããJITã³ã³ãã¤ã©ã»ã¢ã»ã³ãã©ã«ããåçã«ã³ã¼ãçæããã¦ãã¾ãã
æ¥å¹´ã®ç®æ¨
é«ãã«è¨å®ãã¦ããã¦50%ãããéæã§ããã°ããããªãã¨ã
- æé©åã®å®è£
ã«åãçµã
- ã³ã³ãã¤ã©æé©åçè«ãç§ã®å°éãªã®ã§åãå ¥ãããæã
- 第ï¼ä¸ä»£ã®å®è£ ãçµäºãã第ï¼ä¸ä»£ã®å®è£ ãå§ãããã¬ã¸ã¹ã¿ãã·ã³åVMã«ãããã¤ãã£ãJITã§åããã
- REPLãä½ãã
- ã¡ã¿ããã°ã©ãã³ã°æ©è½ã«åãçµã
- åãå ¥ãããé¨åã§ããÏå¼ãæ¡ç¨ããç®çã¯æ§ææ¨ãæè»ã«åãæ±ãçºã
- ç¾ç¶ã§ã¯å®è¡æã«æ§æãå®ç¾©ããæã¾ã§ã§ãã¾ãã
- ã¢ã»ã³ãã©ãèªä½ãã
- ãã«ãã·ã¹ãã ãèªä½ãã
- ç¾å¨ã¯makeã使ã£ã¦ãããã©ããã£ãããªã®ã§ãããèªä½ããã
- æ¨æºã©ã¤ãã©ãªã®å®è£
ãéå§ãã
- å¤åæ°æ´æ°ãæµ®åå°æ°ç¹æ°ãæååãå種ã³ã³ããã»ã¢ã«ã´ãªãºã ãªã©ã
- ã¡ã¿ããã°ã©ãã³ã°ã©ã¤ãã©ãªã®å®è£
ãéå§ãã
- å®è¡ææ§æå®ç¾©ã»å®è¡æã³ã¼ãçæã使ã£ãé¢ç½ãã©ã¤ãã©ãªã®éçºã«åãçµã¿ããã¨æã£ã¦ãããä»ã¯ä»¥ä¸ã®ç©ã«èå³ãããã
- lex/yaccãå¤é¨ãã¼ã«ã¨ãã¦ã§ã¯ãªãã"import lex"ã¨ãã£ãæãã§ããã°ã©ã ä¸ã§importãã¦ä½¿ãããããªç©ãä½ããããã¾ããããã¯ç¬¬ï¼ä¸ä»£rowlã®å®è£ ã«ã使ãããã
- ãã¼ã¸è¨è¿°è¨èªãã¨ããããã¯PostScriptãçæã§ããããã«ãã¦ã¿ãããæ§ææ¨ãããã¼ã°ã©ãã®å³ç¤ºãªã©ããããããã¨ãProject Eulerã¨ãã®èª¬æã§ä½¿ãçµµã¨ããããã使ããã°é¢ç½ãã
- ã°ã©ãè¨è¿°è¨èªãGraphvizã®ãããªç©ã
- ã³ã³ãã¥ã¼ã¿ä»£æ°ãããã¯ç´ç²ã«èå³ãããã®ã§ä½ã£ã¦ã¿ãããimport algebraã¨ãæ¸ãã¦REPLãæ°å¼å¦çã·ã¹ãã ã«åãããç´ æµã§ã¯ãªããã¨ããå¦æ³ã
- Cè¨èªçã®ä»è¨èªã§æ¸ãããã³ã¼ãã®å¼ã³åºãã
- ãã£ã±ãæ¢åè³æºã®æ´»ç¨ã¯å¤§äºã ã¨æãã
- ãã ããå½åã®ããªã·ã¼ãå®ãããrowlæ¬ä½ã»æ¨æºã©ã¤ãã©ãªã¯ä»è¨èªã«ä¾åããªããã®ã«ããã
- rowlç´¹ä»ç¨ã®Webãã¼ã¸ãä½ãããã¨ããã¥ã¢ã«ã
- åå¼·ä¼ããªããã§rowlãç´¹ä»ããããã£ãããªã®ã§ãã¬ã¼ã³ãã¼ã·ã§ã³ãã¼ã«ãrowlã§å®è£ ããã
Project Euler (13ã50)
50åç®ã¾ã§è§£ãã¾ãããæ°å¦ã使ã£ã¦å·¥å¤«ããã¨éã解ããããããããªãã®ã«ã¤ãã¦ã ãèªåã®è§£çãæ¸ãã¾ãã
Problem 15
20x20ã®ã°ãªããã®å·¦ä¸ããå³ä¸ã¾ã§ã®æççµè·¯æ°ãæ±ãã
ããã¯ï¼é
ä¿æ°ã
ã®å¤ãè¨ç®ããã°è¯ãã§ããï¼é
ä¿æ°ã®å¤ã¯ãã¹ã«ã«ã®ä¸è§å½¢ã®å¤ãä¸ããä¸ã¸è¨ç®ãã¦ããæ¹æ³ãå¹ççã§ããã¤ã¾ãã以ä¸ã®æ¼¸åå¼ã使ãã¾ãã
ã³ã¼ãã¯æ¬¡ã®ããã«ãªãã¾ãã
a = [1,1] 2.upto 40 do |n| n.downto 0 do |k| a[k] = (k == 0 || k == n) ? 1 : a[k-1] + a[k] end end puts a[20]
a[k]ã®è¨ç®ã«a[k-1]ã使ãã¾ããããå å´ã®ã«ã¼ãã¯downtoã§ãã
Problem 21,23
Problem 21: 10000以ä¸ã®å ¨ã¦ã®åææ°ã®åãæ±ãã
Problem 23: 2ã¤ã®éå°æ°ã®åã§è¡¨ãããªãæ°ã®åãæ±ãã
åææ°ãéå°æ°ãç´æ°ã®åãç¨ãã¦å¤å®ãã¾ããç´æ°ã®åã¯Nã®å æ°å解ã
ã®æ
ã§æ±ã¾ããããªã®ã§ãProblem 12ã¨åæ§ã«ãã¦é«éã«æ±ããäºãã§ãã¾ãã
ä¾ãã°Problem 21ã®å ´åã¯ä»¥ä¸ã®æ§ãªæãã«ãªãã¾ãã
N = 30000 d = Array.new(N+1,1) exp = Array.new(N+1) 2.upto(N) do |n| if d[n] == 1 then exp.fill(0) n.step(N, n) do |k| exp[k] = exp[k/n] + 1 d[k] *= (1-n**(exp[k]+1))/(1-n) end end end sum = 0 2.upto(10000) do |n| a = d[n]-n b = d[a]-a sum += n if a != b && b == n end puts sum
å®è¡æéã¯0.36ç§ç¨åº¦ã§ãã
Problem 26
1/dã®å¾ªç°ç¯ã®é·ããæ大ã¨ãªããããªd (< 1000)ãæ±ãã
循ç°ç¯ã®é·ããkã¨ããã¨
ãæ´æ°ã¨ãªããããªã®ã§
ãæç«ãããããªkã調ã¹ãã°è¯ãã§ãã
Problem 27
n^2 + an + b (n=0,1,2,...)ãçæããç´ æ°åãæé·ã¨ãªããããªa,b(|a|<1000,|b|<1000)ãæ±ããã
n=0ã§ç´ æ°ã§ããå¿
è¦ãããããbã¯ç´ æ°ã
n=1ã§ç´ æ°ã§ããå¿
è¦ããããã1+a+bã¯ç´ æ°ãå¾ã£ã¦aã¯å¥æ°ã§ãããã«1+a+b > 0ããªã©ã®å¿
è¦æ¡ä»¶ã調ã¹ã¦æ¢ç´¢ç¯å²ãçµãã°è¯ãã§ãã
N = 20000 sieve = [] primes = [] 2.upto(N) do |n| next if sieve[n] primes.unshift(n) if n < 1000 (2*n).step(N,n) {|k| sieve[k] = true} end max_len = 0 max = 0 primes.each do |b| break if b <= max_len (-b+2).step(999,2) do |a| next if sieve[1+a+b] n = 0 while true p = n*n + a*n + b break if p < 0 || (p < N && sieve[p]) raise "N is too small" if p >= N n+=1 end max, max_len = a*b, n if n > max_len end end puts max
å®è¡æéã¯0.40ç§ã
Problem 28
ä¸ã®æ§ã«ãã¦èºæç¶ã«ä¸¦ã¹ã1001x1001ã®æ°ååã®ã対è§ã«ããæ°ã®åãæ±ããã
21 22 23 24 25 20 7 8 9 10 19 6 1 2 11 18 5 4 3 12 17 16 15 14 13
群æ°åã¨ãã¦èãã¦ãä¸è¾ºã®é·ãã2*n+1ã®æã®åã®ä¸è¬é
ãæ±ããã¨
ãªã®ã§ã¤ã¾ã
ã«n=500ã代å
¥ãã¦çµããã
Problem 31
1ãã³ã¹ãã1ãã³ã硬貨ã¾ã§ã使ã£ã¦ã2ãã³ããæ¯æãæ¹æ³ã¯ä½éããï¼
以前書いたようにして漸åå¼ãç«ã¦ãã
Problem 39
p = a + b + cãã¤a^2+b^2=c^2
ã§ããèªç¶æ°a,b,cãèãããæã解ã®æ°ãå¤ããªãpã®å¤ãæ±ããã
ããã¯Problem 9ã¨åããï¼å
ï¼æ¬¡ä¸å®æ¹ç¨å¼ã®åé¡ãªã®ã§æ¢ç´¢ã¯ä¸è¦ãcãæ¶å»ãã¦å æ°å解ããã¨
ã¨ãªãã®ã§ãã¾ãpã¯å¶æ°ã§ãããã¨ãå¿
è¦ãããã§a <= bã¨ããã°p-a >= p-bã ãã
ã®ç¯å²ã§p^2/2ã®ç´æ°ã¨ãªãp-aã®åæ°ãæ°ããã°è¯ãã§ãã
max = 0 max_p = 0 4.step(1000,2) do |p| count = 0 Math.sqrt(p*p/2).ceil.upto(p) do |k| count += 1 if (p*p/2)%k == 0 end max, max_p = count, p if max < count end puts max_p
å®è¡æéã¯0.08ç§ã
Problem 40
0.123456789101112131415161718192021...
ã®ãããªç¡éå°æ°ã®å°æ°ç¬¬nä½ãdnã¨ãã¦
d1 * d10 * d100 * d1000 * d10000 * d100000 * d1000000
ãæ±ãã
næ¡ã®æ°ã第n群ã¨ãã¦ç¾¤æ°åçã«ããã°ããã§ãã
r = 1 [1,10,100,1000,10000,100000,1000000].each do |n| k, s = 0, 0 while n > 9*10**k*(k+1) n -= 9*10**k*(k+1) k += 1 end d = (n-1) % (k+1) n = 10**k + (n-1)/(k + 1) r *= (n / 10**(k-d))%10 end puts r
å®è¡æéã¯0.01ç§ã
Problem 42,44,45
ãããã®åé¡ã§ã¯ä¸è§æ°T(n),äºè§æ°P(n)ï¼å
è§æ°H(n)ãæ±ãã¾ããããããã¯ä»¥ä¸ã®ããã«ãã¦å¤ããã¤ã³ããã¯ã¹ãç°¡åã«æ±ããäºãã§ãã¾ããããã«åºã¥ãã¦è§£çãä½æããã°ä¸æãã§ãã¾ãã
Problem 47
é£ç¶ãã4æ´æ°ã§ãå ¨ã¦ã4ã¤ã®ç´ å æ°ãããªãæ°ã§ãããã®ãæ±ãã
ãç´ å æ°ã®æ°ãã使ãã¾ããããããProblem 21,23ã¨åæ§ã«å復ã«ããæ±ãããã¾ãã
N = 1000000 sieve = Array.new(N+1, 0) 2.upto(N) do |n| if sieve[n] == 0 then n.step(N, n) do |k| sieve[k] += 1 end end if n > 4 && (n-3..n).all? {|k| sieve[k] == 4} puts n-3 exit end end
å®è¡æéã¯2.75ç§ã