宇宙船のコンピュータの整数演算ユニット作成し、船員を助けよう！

#宇宙船のコンピュータの整数演算ユニット作成し、船員を助けよう！!

![illustrain09-utyuu5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248419/5d2515e9-292e-88d8-0887-80c3a930ce5a.png)

## 問題
以下の入力の場合、実装して、出力の配列[0]の値を示せ。

#### 入力
```
[1,1,28,3,1,1,2,3,1,3,4,3,1,5,0,3,2,9,1,19,1,9,19,23,1,23,5,27,2,27,10,31,1,6,31,35,1,6,35,39,2,9,39,43,1,6,43,47,1,47,5,51,1,51,13,55,1,55,13,59,1,59,5,63,2,63,6,67,1,5,67,71,1,71,13,75,1,10,75,79,2,79,6,83,2,9,83,87,1,5,87,91,1,91,5,95,2,9,95,99,1,6,99,103,1,9,103,107,2,9,107,111,1,111,6,115,2,9,115,119,1,119,6,123,1,123,9,127,2,127,13,131,1,131,9,135,1,10,135,139,2,139,10,143,1,143,5,147,2,147,6,151,1,151,5,155,1,2,155,159,1,6,159,0,99,2,0,14,0];
```
#### 出力
入力配列が同じサイズの配列

#####例
```
入力：[1,0,0,0,99] 。出力： [2,0,0,0,99]    原因 (1 + 1 = 2).
入力：[2,3,0,3,99]。出力：[2,3,0,6,99]       原因(3 * 2 = 6).
入力：[2,4,4,5,99,0]。出力：[2,4,4,5,99,9801]  原因(99 * 99 = 9801).
入力：[1,1,1,4,99,5,6,0,99] 。出力：[30,1,1,4,2,5,6,0,99]
```

#####制約
なし。言語は限らない。

#####ボーナス
出力配列[0]が19690720となる場合の入力配列[1]と[2]の値は何番でしょう。
取りうる範囲は0~99とする。

##回答
#####回答例１（JavaScript）
~~~javascript
const intCodeComputer = (intCode=[99]) => {
   for(let i=0; i<intCode.length; i+=4){
       if(intCode[i] === 99) return intCode;
       switch(intCode[i]) {
           case 1:
               intCode[intCode[i+3]] = intCode[intCode[i+1]] + intCode[intCode[i+2]];
               break;
           case 2:
               intCode[intCode[i+3]] = intCode[intCode[i+1]] * intCode[intCode[i+2]];
               break;
           default: break;
       }
   }
};

const answer = intCodeComputer([...PUZZLE_INPUT]);
console.log(answer[0]);
~~~

#####回答例２（C#）
~~~C#
static void Main(string[] args)
{
   Console.WriteLine(string.Join(',', OperationRecursive(args, 0)));
}

private static int[] OperationRecursive(int[] sources, int step)
{
   int calc(Func<int, int, int> f, int x, int y) => f(x, y);

   var targets = sources.Skip(step * 4).Take(4).ToArray();

   if (targets[0] == 99)
       return sources;
   if (targets[0] == 1)
       sources.SetValue(calc((x, y) => x + y, sources[targets[1]], sources[targets[2]]), targets[3]);
   if (targets[0] == 2)
       sources.SetValue(calc((x, y) => x * y, sources[targets[1]], sources[targets[2]]), targets[3]);

   return OperationRecursive(sources, step + 1);
}
~~~
#####回答例３（GO）
~~~GO
func main() {
 numlist := []int{}
 for i := 0; i < len(numlist); i += 4 {
   var a = numlist[i+1]
   var b = numlist[i+2]
   var c = numlist[i+3]

   if numlist[i] == 1 {
     var d = numlist[a] + numlist[b]
     numlist[c] = d
   }

   if numlist[i] == 2 {
     var d = numlist[a] * numlist[b]
     numlist[c] = d
   }

   if numlist[i] == 99 {
     break
   }
 }
 fmt.Println(numlist[0])
}
~~~

#####回答例４（Java）
~~~Java
public class Main {
   public static void main(String[] args) {
       int [] arrayCode = {};
       for(int i=0;i<arrayCode.length; i+=4)
       {
           if(arrayCode[i]==99){
               break;
           }

           if(arrayCode[i]==1)
           {
               arrayCode[arrayCode[i+3]] = arrayCode[arrayCode[i+1]] + arrayCode[arrayCode[i+2]];
           }
           else if(arrayCode[i]==2)
           {
             arrayCode[arrayCode[i+3]] = arrayCode[arrayCode[i+1]] * arrayCode[arrayCode[i+2]];
           }
       }
       System.out.print(arrayCode[0]);
   }
}
~~~

#####回答例５（Perl）
~~~Perl
my @array = (1,0,0,0,99);

sub calc {
   my @array = @_;
   my $length = @array;

   for (my $i = 0; $i < $length; $i+=4) {
       ($array[$i] == 99) && (last);

        if ($array[$i] == 1) {
            $array[$array[$i+3]] = $array[$array[$i+1]] + $array[$array[$i+2]]
        } elsif ($array[$i] == 2) {
           $array[$array[$i+3]] = $array[$array[$i+1]] * $array[$array[$i+2]]
        }
   }
   return $array[0];
}

$result = &calc(@array);

print "$result";
~~~