พายเรือแคนู Whitewater มาก


28

คุณพายเรือแคนูไปตามแม่น้ำสายน้ำที่ค่อนข้างเร็ว ทันใดนั้นไม้พายของคุณก็ระเบิดและคุณก็พบว่าตัวเองตกอยู่ในสถานการณ์อันตรายที่พุ่งลงแม่น้ำอย่างรวดเร็วโดยไม่มีไม้พาย โชคดีที่คุณยังมีทักษะการเขียนโปรแกรมดังนั้นคุณตัดสินใจที่จะแกะสลักโปรแกรมที่ด้านข้างของเรือแคนูเพื่อช่วยให้คุณรอดจากกระแสน้ำเชี่ยว อย่างไรก็ตามมีพื้นที่ผิวด้านข้างของแคนูไม่มากนักในการเขียนโปรแกรมด้วยดังนั้นคุณต้องทำให้โปรแกรมสั้นที่สุดเท่าที่จะทำได้

แม่น้ำสามารถแสดงเป็น 8 โดย 16 ตาราง เราจะติดป้ายคอลัมน์ด้วยตัวเลข0ไป7และแถวที่มีตัวเลขการ015

        y
--------15
--------14
--------13
--------12
--------11
--------10
--------9
--------8
--------7
--------6
--------5
--------4
--------3
--------2
--------1
--------0
01234567
x

ด้านบน: แม่น้ำธรรมดาที่สงบนิ่งไม่มีสิ่งกีดขวาง ตามธรรมชาติแล้วนี่ไม่ใช่แม่น้ำที่คุณอยู่

คุณเริ่มที่พิกัด (4, 0) และจากนั้นเลื่อนขึ้นไปตามแม่น้ำอย่างไม่สามารถควบคุม (เช่นเวกเตอร์(0,1)) จนกว่าคุณจะชนหิน (แทนด้วยoตัวอย่างในตัวอย่างเหล่านี้) เมื่อคุณชนหินคุณจะมีโอกาส 55% ที่จะเคลื่อนที่ผ่านก้อนหินไปทางซ้าย (เช่นเวกเตอร์(-1,1)) และ 45% โอกาสที่จะเคลื่อนที่ผ่านก้อนหินไปทางขวา (เช่นเวกเตอร์(1,1)) หากเรือแคนูอยู่ทางด้านซ้ายหรือด้านขวาคอลัมน์จะเคลื่อนที่ไปทางกึ่งกลางเสมอ หากไม่มีหินมันจะเคลื่อนที่ขึ้นไปตรง

        y
----x---15
----xo--14
-o--x---13
----x---12
---ox---11
---x----10
---xo---9
---ox---8
----xo--7
-----x--6
----ox--5
-o--x---4
----x---3
----xo--2
----x---1
----x---0
01234567

ด้านบน: เส้นทางที่เป็นไปได้ที่เรือแคนูอาจใช้แทนตัวละคร x

ให้แผนที่แม่น้ำเขียนโปรแกรมที่จะส่งออกความน่าจะเป็นของการพายเรือแคนูที่คอลัมน์ที่กำหนด

ยอมรับอินพุตในวิธีใดก็ได้ที่สะดวกสำหรับโปรแกรมของคุณ (เช่น STDIN, อาร์กิวเมนต์บรรทัดคำสั่งraw_input(), การอ่านจากไฟล์ ฯลฯ ) ส่วนแรกของอินพุตเป็นจำนวนเต็มเดียวจาก 0 ถึง 7 แสดงถึงคอลัมน์โปรแกรมจะหาความน่าจะเป็น ต่อไปนี้เป็นรายการของสิ่งอันดับในรูปแบบที่x,yแสดงถึงตำแหน่งของหิน

ตัวอย่าง:

การป้อนข้อมูล:

4 4,1 5,5 3,5

สิ่งนี้จะบ่งบอกถึงแม่น้ำที่มีก้อนหินที่ตำแหน่ง (4,1), (5,5) และ (3,5) และถามถึงความน่าจะเป็นของการพายเรือแคนูที่สิ้นสุดที่คอลัมน์ที่ 4

เอาท์พุท:

0.495

โปรดสังเกตว่าในตัวอย่างนี้ตำแหน่งของหินมีความสมมาตรทำให้สามารถแก้ไขปัญหาได้ด้วยการแจกแจงทวินาม กรณีนี้จะไม่เกิดขึ้นเสมอไป!

นอกจากนี้แม่น้ำจะสามารถข้ามได้เสมอ นั่นคือจะไม่มีหินสองก้อนที่อยู่ติดกันในแนวนอน ดูความคิดเห็นของ Glennเพื่อเป็นตัวอย่างของกรณีที่เป็นไปไม่ได้

นี่คือรหัสกอล์ฟจำนวนตัวอักษรต่ำที่สุดจึงเป็นผู้ชนะ อย่าลังเลที่จะถามคำถามในความคิดเห็นหากข้อกำหนดไม่ชัดเจน


8
ส่วนที่น่าขันก็คือโปรแกรมไม่ได้ช่วยให้ใครรอดจากกระแสน้ำเชี่ยว มันไม่บอกพวกเขาว่ามีโอกาสที่พวกเขาจะเอาตัวรอดแม้ว่า.
Absinthe

1
จะเกิดอะไรขึ้นเมื่อหินสองก้อนขึ้นไปอยู่ติดกันเป็นแถว? เช่นหากแผนที่เป็น "0 1,0 1,1" เรือแคนูจะชนเข้ากับหินที่ 1,1 (a) เงื่อนไขไม่ได้รับอนุญาตหรือ (b) ความน่าจะเป็นที่จะสำเร็จหลักสูตรคือ 0
Glenn Randers-Pehrson

1
อาโอเค. ขออภัยฉันพลาดส่วนนั้นไป
Doorknob

3
ความคิดสุดท้าย: "บางทีการสร้างเรือแคนูที่ตั้งโปรแกรมได้ไม่ใช่ทางออกที่ดีที่สุดสำหรับปัญหาการใช้ไม้พายที่ระเบิดได้"
Kai

2
ฉันต้องการที่จะเห็นสิ่งที่ดูเหมือนว่าเมื่อใบพัดระเบิด
Robbie Wxyz

คำตอบ:


4

GolfScript 105 ตัวอักษร

~](\2/:A;8,{4=}%15,{:B;{20*}%A{~B={[\\,.1,*\[2$=..20/9*:C-\~)C]+(1,\+1,6*2$8>+]zip{{+}*}%.}*;}/}/=20-15?*

เวอร์ชัน GolfScript ซึ่งนานกว่าที่ตั้งใจไว้มาก - แต่ความพยายามในแต่ละครั้งด้วยวิธีการที่แตกต่างกันนั้นยิ่งนานกว่า อินพุตต้องถูกกำหนดบน STDIN

ตัวอย่าง:

> 4 4,1 5,5 3,5
99/200

รหัสข้อเขียน:

# Evaluate the input
#  - stack contains the first number (i.e. column)
#  - variable A contains the rock coordinates (pairs of X y)
#    where X is an array of length x (the coordinate itself)
~](\2/:A;

# Initial probabilities
#  - create array [0 0 0 0 1 0 0 0] of initial probabilities
8,{4=}%

# Loop over rows 
15,{:B;           # for B = 0..14
  {20*}%          #   multiply each probability by 20
  A{              #   for each rock 
    ~B={          #     if rock is in current row then
                  #       (prepare an array of vectors [v0 vD vL vR] 
                  #       where v0 is the current prob. before rocks,
                  #       vD is the change due to rocks,
                  #       vL is a correction term for shifting out to the left
                  #       and vR the same for the right side)
      [\\         #       move v0 inside the array
      ,           #       get x coordinate of the rock
      .1,*        #       get [0 0 ... 0] with x terms
      \[2$=       #       get x-th item of v0
      ..20/9*:C-  #       build array [0.55P -P 0.45P]
      \~)C]+      #       and append to [0 0 ... 0]
      (1,\+       #       drop the leftmost item of vD and prepend [0] again
                  #       which gives vL
      1,6*2$8>+   #       calculate vR using the 8th item of vD
      ]           #       
      zip{{+}*}%  #       sum the columns of this list of vectors
      .           #       dummy dup for end-if ;
    }*;           #     end if
  }/              #   end for
}/                # end for

# take the n-th column and scale with 20^-15
=
20-15?*

11

Ruby, 204 191 172 ตัวอักษร

c,*r=gets.split
o=[0]*8
s=->x,y,p{y>14?o[x]+=p :(r.index("#{x},#{y+=1}")?(x<1?s[x+1,y,p]:(x>6?s[x-1,y,p]:(s[x-1,y,p*0.55]+s[x+1,y,p*0.45]))):s[x,y,p])}
s[4,0,1]
p o[c.to_i]

y == 15มันซ้ำเลียนแบบทุกการติดตามอาจจะเป็นผลขณะที่การรักษาความน่าจะเป็นของแต่ละผลของแต่ละคนแล้วก็เพิ่มความน่าจะเป็นที่เคาน์เตอร์สะสมเมื่อ

เทคนิคแฟนซี:

  • c,*r=gets.split- โอเปอเรเตอร์ "splat" ( *) ใช้องค์ประกอบที่เหลือทั้งหมดของgets.splitและติดเข้าไปในrอาร์เรย์

  • next {something} if {condition}: เทียบเท่ากับ

    if {condition}
        {something}
        return
    end
    

    "ค้นพบ" โดยการพัฒนาจากif condition; something; return; endไปreturn something if conditionเป็นbreak something if conditionแล้วฉันคิดว่าฉันจะลอง "ผู้ดำเนินการวนรอบ" ที่สั้นลงเพื่อดูว่ามันจะใช้งานได้หรือไม่

  • ขอบคุณ @ MartinBüttnerที่แนะนำให้ใช้ผู้ประกอบการที่ถูกล่ามโซ่ (ซึ่งกลายเป็นบรรทัดที่สามขนาดใหญ่ในรหัส golfed ด้านบน) และกำจัดจุดดังกล่าว (ซึ่งบันทึกอักขระ 19 (!))

    ฉันใช้กลอุบายที่ค่อนข้างแฟนซีกับสิ่งเหล่านั้น แต่ฉันรู้ว่าs[foo],s[bar]มันไม่ทำงานใน Ruby สำหรับการเรียกสองวิธีในหนึ่งคำสั่ง ดังนั้นในครั้งแรกที่ผมเปลี่ยนไป(_=s[foo],s[bar])(ตัวแปรดัมมี่) s[foo]+s[bar]แต่แล้วฉันตระหนักฉันสามารถเพิ่มและโยนออกไปคืนค่า: นี้จะทำงานเพราะโทรไปsจะเท่านั้นที่เคย "กลับ" สายอื่น ๆ ที่จะsหรือหมายเลข ( o[x]+=p) nilดังนั้นผมจึงไม่ต้องกังวลเกี่ยวกับการตรวจสอบ

  • การปรับให้เหมาะสมต่าง ๆ อื่น ๆ : pแทนที่จะใช้putsสำหรับการพิมพ์ตัวเลข<1แทนที่จะเป็น==0(ตั้งแต่เรือแคนูไม่เคยออกจากแม่น้ำ) และการเปรียบเทียบที่คล้ายกันที่อื่น[0]*8เพื่อความน่าจะเป็นเริ่มต้นเนื่องจากหมายเลขของรูบี้มักจะ "ผ่านตามตัวอักษร"

Ungolfed:

column, *rocks = gets.chomp.split
outcomes = Array.new(8, 0)
simulate = -> x, y, probability {
    if y == 15
        outcomes[x] += probability
    elsif rocks.index("#{x},#{y + 1}")
        case x
        when 0 then simulate[x + 1, y + 1, probability]
        when 7 then simulate[x - 1, y + 1, probability]
        else
            simulate[x - 1, y + 1, probability * 0.55]
            simulate[x + 1, y + 1, probability * 0.45]
        end
    else
        simulate[x, y + 1, probability]
    end
}
simulate[4, 0, 1.0]
p outcomes
puts outcomes[column.to_i]

จะยังสั้นกว่าหรือไม่หากจะรวบรวมทั้งหมดเหล่านั้นnext X if Yลงในตัวดำเนินการแบบไตรภาค คุณสามารถเพิ่มมันเข้าไปในเคล็ดลับ Ruby ได้!
Martin Ender

@ MartinBüttnerอ๋อจริง ๆ แล้วมันสั้นกว่าตัวละครมากถึง 19 ตัว! ขอบคุณแม้ว่ามันจะมีผลข้างเคียงที่โชคร้ายของสายยาวที่น่าขัน: P
Doorknob

5

C # 418 364 ไบต์

ทำโปรแกรม C # ให้สมบูรณ์โดยคาดหวังอินพุตจาก STDIN ทำงานโดยการอ่านหินลงในอาร์เรย์ของทุกตำแหน่งในแม่น้ำสร้างแผนที่อย่างมีประสิทธิภาพจากนั้นมันจะทำการวนซ้ำ 16 ครั้งในการเคลื่อนย้ายความน่าจะเป็นไปรอบ ๆ อาเรย์ทศนิยม 8 หน้ากว้างก่อนที่จะแสดงผลลัพธ์

using C=System.Console;class P{static void Main(){var D=C.ReadLine().Split();int i=0,j=D.Length;var R=new int[8,16];var p=new decimal[8];for(p[4]=1;--j>0;)R[D[j][0]-48,int.Parse(D[j].Substring(2))]=1;for(;i<16;i++){var n=new decimal[j=8];for(;j-->0;)if(R[j,i]>0){n[j<1?1:j-1]+=p[j]*0.55M;n[j>6?6:j+1]+=p[j]*0.45M;}else n[j]+=p[j];p=n;}C.WriteLine(p[D[0][0]-48]);}}

รหัสที่จัดรูปแบบ:

using C=System.Console;

class P
{
    static void Main()
    {
        var D=C.ReadLine().Split();
        int i=0,j=D.Length;
        var R=new int[8,16];
        var p=new decimal[8];

        for(p[4]=1;--j>0;) // read rocks into map (R)
            R[D[j][0]-48,int.Parse(D[j].Substring(2))]=1;

        for(;i<16;i++) // move up the river
        {
            var n=new decimal[j=8];
            for(;j-->0;)
                if(R[j,i]>0)
                { // we hit a rock!
                    n[j<1?1:j-1]+=p[j]*0.55M;
                    n[j>6?6:j+1]+=p[j]*0.45M;
                }
                else
                    n[j]+=p[j];
            p=n; // replace probability array
        }

        C.WriteLine(p[D[0][0]-48]); // output result
    }
}

+1 สำหรับการใช้โอเปอเรเตอร์ "ไปที่" ( for(;j-->0;)) คุณสามารถกำจัดคู่ของตัวอักษรแม้ว่าโดยการแทนที่สุดท้ายโดยC.WriteLine C.Writeนอกจากนี้หากคุณใช้floatแทนคุณdecimalจะสามารถประหยัดได้อีกสองไบต์
Christoph Böhmwalder

@ HackerCow การปฏิบัติมาตรฐาน;) ได้รับประโยชน์สูงสุดจากลูปของคุณ! ฉันกำลังใช้decimalเพราะfloatจะไม่แม่นยำ แต่ทศนิยมควรทำสำหรับปัญหาเหล่านี้ แต่อาจเป็นไปตามที่คุณพูด ฉันจะใส่ในC.Writeถ้าฉันจะจัดการกอล์ฟนี้เพิ่มเติมเพราะมันอาจจะใกล้กับสเป็คมากกว่าC.WriteLineที่ฉันไม่คิดว่า 4 ไบต์รับประกันการแก้ไขสำหรับโปรแกรมขนาดนี้;)
VisualMelon

2

Haskell, 256 ไบต์

import Data.List
m=map;v=reverse
a p n x=take n x++(x!!n+p:drop(n+1)x)
l=abs.pred
o[_,n]s=n#(s!!n)$s
n#p=a(11*p/20)(l n).a(9*p/20)(7-(l$7-n)).a(-p)n
b=0:0:0:0:1:b
k(c:w)=(foldl1(.)$m o$v$sort$m(v.read.('[':).(++"]"))w)b!!read c
main=getLine>>=print.k.words

นี่เป็นเวอร์ชั่นที่ไม่ดีมากพร้อมกับเทคนิคบางอย่างที่ใช้:

import Data.List

-- Types to represent the distribution for the canoe's location
type Prob = Double
type Distribution = [Prob]

-- Just for clarity..
type Index = Int

-- An Action describes some change to the probability distribution
-- which represents the canoe's location.
type Action = Distribution -> Distribution

-- Helper to add k to the nth element of x, since we don't have mutable lists.
add :: Index -> Prob -> Action
add n k x = take n x ++ [p] ++ drop (n + 1) x
    where p = k + x!!n  

-- A trick for going finding the index to the left of n,
-- taking the boundary condition into account.
leftFrom n = abs (n - 1)

-- A trick for getting the other boundary condition cheaply.
rightFrom = mirror . leftFrom . mirror
    where mirror = (7 -)

-- Make the action corresponding to a rock at index n.
doRock :: Index -> Action
doRock n p = (goLeft . goRight . dontGoForward) p
    where goLeft  =  (leftFrom n) `add` (p_n * 11/20)
          goRight = (rightFrom n) `add` (p_n * 9/20)
          dontGoForward =  (at n) `add` (-p_n)
          p_n = p!!n
          at = id

initialProb = [0,0,0,0,1,0,0,0]

-- Parse a pair "3,2" ==> (3,2)
readPair :: String -> (Index,Index)
readPair xy = read $ "(" ++ xy ++ ")"

-- Coordinate swap for the sorting trick described below.
swap (x,y) = (y,x)

-- Put it all together and let it rip!
main = do
    input <- getLine
    let (idx : pairs) = words input
    let coords = reverse . sort $ map (swap . readPair) pairs
    let rockActions = map (doRock . snd) coords
    let finalProb = (foldl1 (.) rockActions) initialProb
    print $ (finalProb !! read idx)

เคล็ดลับสุดท้ายที่ฉันใช้คือการสังเกตว่าคุณสามารถทำราวกับว่าก้อนหินในแถวเดียวแยกออกจากกันด้วยจำนวนเล็กน้อย กล่าวอีกนัยหนึ่งคุณสามารถใช้หม้อแปลงไฟฟ้าการกระจายความน่าจะเป็นสำหรับหินแต่ละก้อนในแถวเดียวกันตามลำดับและตามลำดับที่คุณต้องการแทนที่จะใช้พวกมันทั้งหมดพร้อมกัน วิธีนี้ใช้งานได้เนื่องจากปัญหาไม่อนุญาตหินสองก้อนที่อยู่ติดกันในแนวนอน

ดังนั้นโปรแกรมจะเปลี่ยนตำแหน่งของหินแต่ละก้อนให้เป็นหม้อแปลงกระจายความน่าจะเป็นซึ่งได้รับคำสั่งจากพิกัด y ของหิน หม้อแปลงจะถูกล่ามโซ่ตามลำดับและนำไปใช้กับการกระจายความน่าจะเป็นเริ่มต้น และนั่นคือ!


2

Perl 169 ไบต์

อ่านจาก STDIN

$_=<>;s/ (.),(\d+)/$s{$1,$2}=1/eg;/./;$x{4}=1.0;for$y(1..15){for$x(0..7){if($s{$x,$y}){$x{$x-1}+=$x{$x}*($x%7?.55:1);$x{$x+1}+=$x{$x}*($x%7?.45:1);$x{$x}=0}}}print$x{$&}

ตรงไปตรงมาโดยนัยใช้คอลัมน์ -1 และ 8 เพื่อทำให้กรณีขอบเรียบขึ้น ความน่าจะเป็นสามารถแพร่กระจายไปยังแต่ละระดับถัดไปได้อย่างปลอดภัยเพราะมีหินอยู่ติดกันดังนั้นจึงมีความเพียงพอในการวิ่งเพียงครั้งเดียว


2

PHP, 358

การใช้กำลังสมองเพื่อกำหนดเส้นทางที่เป็นไปได้และความน่าจะเป็นของพวกเขานั้นยากและอาจต้องใช้รหัสมากกว่าการจำลองอุบัติเหตุเรือแคนู 1,000,000 ครั้ง โอ้มนุษยชาติ!

define('MX',7);
define('MY',16);
define('IT',1000000);
error_reporting(0);

function roll(){return rand()%100 > 44;}

function drift($rocks,$print=false) {
    for($px=4,$py=0;$py<MY;$py++) {
        if(isset($rocks[$px][$py])){
            if(roll()) $px--;
            else $px++;
        }
        else if($px==0) $px++;
        else if($px==MX) $px--;
        if($print) {
            for($i=0;$i<MX;$i++){
                if($i==$px) echo 'x';
                else if(isset($rocks[$i][$py])) echo 'o';
                else echo '-';
            }
            echo " $py\n";
        }
    }
    return $px;
}

$input = $argv[1];
$tmp = explode(' ',$input);
$end_target = array_shift($tmp);
$rocks = array();
array_map(function($a) use(&$rocks) {
    list($x,$y) = explode(',',$a);
    $rocks[$x][$y]=1;
}, $tmp);

$results=array();
for($i=0;$i<IT;$i++) {
    $results[drift($rocks)]++;
}

drift($rocks, true); // print an example run

foreach($results as $id=>$result) {
    printf("%d %0.2f\n", $id, $result/IT*100);
}

ตัวอย่าง:

php river.php "4 4,1 5,5 3,3 6,2 9,4 12,3 13,5"
----x-- 0
---xo-- 1
---x--o 2
--xo--- 3
--x---- 4
--x--o- 5
--x---- 6
--x---- 7
--x---- 8
--x---- 9
--x---- 10
--x---- 11
--x---- 12
--x---- 13
--x---- 14
--x---- 15
4 49.53
2 30.18
6 20.29

แข็งแรงเล่นกอล์ฟ:

<? function d($r){for($x=4,$y=0;$y<16;$y++){if(isset($r[$x][$y])){if(rand()%100>44)$x--;else $x++;}elseif($x==0)$x++;elseif($x==7)$x--;}return $x;}$t=explode(' ',$argv[1]);$e=array_shift($t);$r=array();array_map(function($a)use(&$r){list($x,$y)=explode(',',$a);$r[$x][$y]=1;},$t);$c=0;for($i=0;$i<1000000;$i++){if(d($r)==$e)$c++;}printf("%.4f", $c/1000000);

รุ่นนี้ไม่ได้ทำการพิมพ์ที่สวยงามใด ๆ และส่งออกความน่าจะเป็นลอยของท่าจอดเรือแคนูที่ตำแหน่งที่ระบุ

# php river_golf.php "4 4,1 5,5 3,3 6,2 9,4 12,3 13,5"
0.4952

ฉันคิดว่ารูปแบบการป้อนข้อมูลที่นี่ปิดเล็กน้อยเช่น river.php ควรให้ 0.561375 ใน "5 4,4 1,5 5,3 3,6 2,9 4,12 3,13"
Matt Noonan

@ Mattoonan เป็นวันที่หยาบกร้าน ฉันน่าจะแก้ไขได้ ...
Sammitch

2

PHP, 274

ฉันไม่สามารถอ่าน / เขียน GolfScript เพื่อช่วยชีวิตของฉันได้ แต่การจ้องมองเหนือสิ่งที่ @ Howard ส่งให้ฉันไปในทิศทางที่ดีกว่าการจำลองอุบัติเหตุเรือแคนู 1 ล้านครั้ง

เริ่มต้นด้วยอาร์เรย์ของความน่าจะเป็นสำหรับตำแหน่งเริ่มต้นเราสามารถแบ่งตัวเลขเหล่านั้นทุกครั้งที่พบหิน

function psplit($i){ return array(.55*$i,.45*$i); }
function pt($a) {
    foreach($a as $p) {
        printf("%1.4f ", $p);
    }
    echo "\n";
}

$input = $argv[1];
$tmp = explode(' ',$input);
$end_target = array_shift($tmp);
$rocks = array();
array_map(function($a) use(&$rocks) {
    list($x,$y) = explode(',',$a);
    $rocks[$x][$y]=1;
}, $tmp);

$state = array(0,0,0,0,1,0,0,0);
pt($state);
for($y=1;$y<16;$y++){
    for($x=0;$x<8;$x++){
        if(isset($rocks[$x][$y])){
            echo('   o   ');
            list($l,$r)=psplit($state[$x]);
            $state[$x]=0;
            $state[$x-1]+=$l;
            $state[$x+1]+=$r;
        } else { echo '   -   '; }
    }
    echo "\n";
    pt($state);
}

ตัวอย่างผลลัพธ์:

# php river2.php "4 4,1 5,5 3,3 6,2 9,4 12,3 13,5"
0.0000 0.0000 0.0000 0.0000 1.0000 0.0000 0.0000 0.0000
   -      -      -      -      o      -      -      -
0.0000 0.0000 0.0000 0.5500 0.0000 0.4500 0.0000 0.0000
   -      -      -      -      -      -      o      -
0.0000 0.0000 0.0000 0.5500 0.0000 0.4500 0.0000 0.0000
   -      -      -      o      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.2475 0.4500 0.0000 0.0000
   -      -      -      -      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.2475 0.4500 0.0000 0.0000
   -      -      -      -      -      o      -      -
0.0000 0.0000 0.3025 0.0000 0.4950 0.0000 0.2025 0.0000
   -      -      -      -      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.4950 0.0000 0.2025 0.0000
   -      -      -      -      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.4950 0.0000 0.2025 0.0000
   -      -      -      -      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.4950 0.0000 0.2025 0.0000
   -      -      -      -      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.4950 0.0000 0.2025 0.0000
   -      -      -      -      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.4950 0.0000 0.2025 0.0000
   -      -      -      -      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.4950 0.0000 0.2025 0.0000
   -      -      -      -      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.4950 0.0000 0.2025 0.0000
   -      -      -      -      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.4950 0.0000 0.2025 0.0000
   -      -      -      -      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.4950 0.0000 0.2025 0.0000
   -      -      -      -      -      -      -      -
0.0000 0.0000 0.3025 0.0000 0.4950 0.0000 0.2025 0.0000

แข็งแรงเล่นกอล์ฟ:

<? $t=explode(' ',$argv[1]);$e=array_shift($t);$r=array();foreach($t as $n){list($j,$k)=explode(',',$n);$r[$j][$k]=1;}$s=array(0,0,0,0,1,0,0,0);for($y=1;$y<16;$y++){for($x=0;$x<8;$x++){if(isset($r[$x][$y])){$s[$x-1]+=$s[$x]*.55;$s[$x+1]+=$s[$x]*.45;$s[$x]=0;}}}echo $s[$e];

ตัวอย่างการเรียกใช้:

# php river2_golf.php "4 4,1 5,5 3,3 6,2 9,4 12,3 13,5"
0.495

1

Haskell, 237

ฉันแค่หวังว่าเรือแคนูมาพร้อมกับ ghc ที่ติดตั้ง ...

เคล็ดลับที่มีรายการไม่สิ้นสุดถูกขโมยจาก Matt Noonan, รุ่งโรจน์ถึงเขา!

import Data.List
r=reverse
(a:b:x)%0=0:a+b:x
x%7=r(r x%0)
x%n=take(n-1)x++(x!!(n-1)+x!!n*0.55:0:x!!(n+1)+x!!n*0.45:drop(n+2)x)
q=0:0:0:0:1:q
u(w:x)=(foldl(%)q.map last.sort.map(r.read.('[':).(++"]"))$x)!!read w
main=interact$show.u.words

ฉันหวังว่าฉันมีเหตุผลที่ถูกต้อง แต่ตัวอย่างของ Matt "5 4,4 1,5 5,3 3,6 2,9 4,12 3,13"ให้ผลตอบแทน0.5613750000000001และตัวอย่างของ OP ที่"4 4,1 5,5 3,5"ให้ผลลัพธ์0.49500000000000005ซึ่งดูเหมือนว่าจะถูกต้องนอกเหนือจากข้อผิดพลาดบางจุดที่ลอยได้

นี่คือการกระทำ:

>>> echo 5 4,4 1,5 5,3 3,6 2,9 4,12 3,13 | codegolf
0.5613750000000001
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.