プログラマ失格になりました

プログラマになりたいなぁと思って、

1時間以内に解けなければプログラマ失格となってしまう5つの問題が話題に

解いてみました、PHPで。
トータル1時間半ちょいかかってしまいプログラマ失格になってしまいました。
残念。

解き方が全くスマートで無く、関数名、変数名もむちゃくちゃ。
ちゃんとしたプログラマになりたいなぁ。
向いてないんだろうなぁ。

問題1

forループ、whileループ、および再帰を使用して、リスト内の数字の合計を計算する3つの関数を記述せよ。

<?php

function sum1(array $list)
{
  $length = count($list);
  $sum = 0;
  for ($i = 0; $i < $length; $i++) {
      $sum += $list[$i];
  }
  return $sum;
}

function sum2(array $list)
{
  $length = count($list);
  $sum = 0;
  $i = 0;
  while ($i < $length) {
      $sum += $list[$i];
      $i++;
  }
  return $sum;
}

function sum3($sum, array $list)
{
    if ($list == []) {
        return $sum;
    }
    else {
        return sum3($sum + $list[0], array_slice($list, 1));
    }
}

echo sum1([1,2,3,4,5]). "\n";
echo sum2([1,2,3,4,5]). "\n";
echo sum3(0, [1,2,3,4,5]). "\n";
$ php 1.php 
15
15
15

問題2

交互に要素を取ることで、2つのリストを結合する関数を記述せよ。例えば [a, b, c]と[1, 2, 3]という2つのリストを与えると、関数は [a, 1, b, 2, c, 3]を返す。

<?php

// $list1の長さ分だけやる前提
function hoge(array $list1, array $list2)
{
    $r = [];
    $length1 = count($list1);
    for ($i = 0; $i < $length1; $i++) {
        $r[] = $list1[$i];
        $r[] = $list2[$i];
    }
    return $r;
}

print_r(hoge(['a', 'b', 'c'], [1,2,3]));
$ php 2.php 
Array
(
    [0] => a
    [1] => 1
    [2] => b
    [3] => 2
    [4] => c
    [5] => 3
)

問題3

最初の100個のフィボナッチ数のリストを計算する関数を記述せよ。定義では、フィボナッチ数列の最初の2つの数字は0と1で、次の数は前の2つの合計となる。例えば最初の10個のフィボナッチ数列は、0, 1, 1, 2, 3, 5, 8, 13, 21, 34となる。

<?php

function fib(array $acc, $n, $m)
{
    if (count($acc) == 100) {
        return $acc;
    }
    else {
        $acc[] = $n + $m;
        return fib($acc, $m, $n + $m);
    }
}

print_r(fib([0, 1], 0, 1));
$ php 3.php 
Array
(
    [0] => 0
    [1] => 1
    [2] => 1
    [3] => 2
    [4] => 3
    [5] => 5
    [6] => 8
    [7] => 13
    [8] => 21
    [9] => 34
    [10] => 55
    [11] => 89
    [12] => 144
    [13] => 233
    [14] => 377
    [15] => 610
    [16] => 987
    [17] => 1597
    [18] => 2584
    [19] => 4181
    [20] => 6765
    [21] => 10946
    [22] => 17711
    [23] => 28657
    [24] => 46368
    [25] => 75025
    [26] => 121393
    [27] => 196418
    [28] => 317811
    [29] => 514229
    [30] => 832040
    [31] => 1346269
    [32] => 2178309
    [33] => 3524578
    [34] => 5702887
    [35] => 9227465
    [36] => 14930352
    [37] => 24157817
    [38] => 39088169
    [39] => 63245986
    [40] => 102334155
    [41] => 165580141
    [42] => 267914296
    [43] => 433494437
    [44] => 701408733
    [45] => 1134903170
    [46] => 1836311903
    [47] => 2971215073
    [48] => 4807526976
    [49] => 7778742049
    [50] => 12586269025
    [51] => 20365011074
    [52] => 32951280099
    [53] => 53316291173
    [54] => 86267571272
    [55] => 139583862445
    [56] => 225851433717
    [57] => 365435296162
    [58] => 591286729879
    [59] => 956722026041
    [60] => 1548008755920
    [61] => 2504730781961
    [62] => 4052739537881
    [63] => 6557470319842
    [64] => 10610209857723
    [65] => 17167680177565
    [66] => 27777890035288
    [67] => 44945570212853
    [68] => 72723460248141
    [69] => 117669030460994
    [70] => 190392490709135
    [71] => 308061521170129
    [72] => 498454011879264
    [73] => 806515533049393
    [74] => 1304969544928657
    [75] => 2111485077978050
    [76] => 3416454622906707
    [77] => 5527939700884757
    [78] => 8944394323791464
    [79] => 14472334024676221
    [80] => 23416728348467685
    [81] => 37889062373143906
    [82] => 61305790721611591
    [83] => 99194853094755497
    [84] => 160500643816367088
    [85] => 259695496911122585
    [86] => 420196140727489673
    [87] => 679891637638612258
    [88] => 1100087778366101931
    [89] => 1779979416004714189
    [90] => 2880067194370816120
    [91] => 4660046610375530309
    [92] => 7540113804746346429
    [93] => 1.2200160415122E+19
    [94] => 1.9740274219868E+19
    [95] => 3.194043463499E+19
    [96] => 5.1680708854858E+19
    [97] => 8.3621143489848E+19
    [98] => 1.3530185234471E+20
    [99] => 2.1892299583456E+20
)

問題4

正の整数のリストを与えられたとき、数を並び替えて可能な最大数を返す関数を記述せよ。例えば、[50, 2, 1, 9]が与えられた時、95021が答えとなる(解答例)。

<?php

function hoge(array $list)
{
    $max = 0;
    foreach ($list as $n) {
        if ($max < $n) {
            $max = $n;
        }
    }
    $ketanum = 0;
    if ($max == 0) {
        $ketanum = 1;
    }
    else {
      while ($max > 0) {
        $max = intval($max / 10);
        $ketanum++;
      }
    }

    $nums = [];
    foreach ($list as $num) {
        $num2 = $num;

    $ketanum2 = 0;
    if ($num2 == 0) {
        $ketanum2 = 1;
    }
    else {
      while ($num2 > 0) {
        $num2 = intval($num2 / 10);
        $ketanum2++;
      }
    }
    $need = $ketanum - $ketanum2;
          $nums[] = [$num * pow(10, $need), $ketanum2, $num];
    }

    usort($nums, function($a, $b) {
        if ($a[0] == $b[0]) {
            return 0;
        }
        return $a[0] > $b[0] ? -1 : 1;
    });

    $r = 0;
    foreach ($nums as $num) {
        $r *= pow(10, $num[1]);
        $r += $num[2];
    }
    return $r;
}

echo hoge([0, 50, 2, 1, 9]). "\n";
echo hoge([50, 2, 1, 9]). "\n";
$ php 4.php 
950210
95021

問題5

1,2,…,9の数をこの順序で、”+”、”-“、またはななにもせず結果が100となるあらゆる組合せを出力するプログラムを記述せよ。例えば、1 + 2 + 34 – 5 + 67 – 8 + 9 = 100となる(解答例)

<?php

function foo($index)
{
    $arr = [];
    $now = 0;
    for ($i = $index; $i < 10; $i++) {
        $now *= 10;
        $now += $i;
        $arr[] = ['num' => $now, 'last' => $i];
    }
    return $arr;
}

function bar($index)
{
    $acc = [];
    $hoge = foo($index);
    foreach ($hoge as $h) {
        $acc[] = ['car' => $h['num'], 'cdr' => bar($h['last'] + 1)];
    }
    return $acc;
}

function flat($car, $cdr)
{
    if ($cdr == []) {
        return [[$car]];
    }
    else {
        $ret = [];
        foreach ($cdr as $x) {
        $hh = flat($x['car'], $x['cdr']);
            foreach ($hh as $h) {
                if ($h !== null) {
                    $ret[] = array_merge([$car], $h);
                }
            }

        }
        return $ret;
    }
}

function calc($s, $x, array $rest) {
    if ($rest == []) {
        return [['s' => $s, 'r' => $x]];
    }
    else {
        $acc = calc("{$s} + {$rest[0]}", $x + $rest[0], array_slice($rest, 1));
        $acc = array_merge($acc, calc("{$s} - {$rest[0]}", $x - $rest[0], array_slice($rest, 1)));
        return $acc;
    }
}

$nums = [];

$aaa = bar(1);
foreach ($aaa as $a) {
    $iii = flat($a['car'],$a['cdr']);
    foreach ($iii as $i) {
        $nums[] = $i;
    }
}

foreach ($nums as $n) {
    $cs = calc($n[0], $n[0], array_slice($n, 1));
    foreach ($cs as $c) {
        if ($c['r'] == 100) {
            echo $c['s']. "\n";
        }
    }
}
$ php 5.php 
1 + 2 + 3 - 4 + 5 + 6 + 78 + 9
1 + 2 + 34 - 5 + 67 - 8 + 9
1 + 23 - 4 + 5 + 6 + 78 - 9
1 + 23 - 4 + 56 + 7 + 8 + 9
12 + 3 + 4 + 5 - 6 - 7 + 89
12 - 3 - 4 + 5 - 6 + 7 + 89
12 + 3 - 4 + 5 + 67 + 8 + 9
123 - 4 - 5 - 6 - 7 + 8 - 9
123 + 4 - 5 + 67 - 89
123 + 45 - 67 + 8 - 9
123 - 45 - 67 + 89