目次

目次

誰かコード書いて!

にょこた
にょこた
最終更新日2017/04/28 投稿日2017/04/28

開発の中で下記の仕様を満たす必要がありました。 社内のコミュニティサイトに投稿してみたところ反響が多かったのでご紹介します。

どんな言語でもいいので、以下の問題を解く、コード書いてください! お願いします。
Q.
[0,1,2,3,4,5,6,7,8,9,10,11,12,20,21,100,101,201]
の数値があります。これを以下の順に並び替えてください。
↓↓
[0,1,10,11,12,100,101,2,20,21,201,3,4,5,6,7,8,9]

そもそもこれ、何順っていうんだ、、

回答1

できました。(python3) 一旦文字列にして戻してみた。
list = [0,1,2,3,4,5,6,7,8,9,10,11,12,20,21,100,101,201]
print(list)
list_str = [str(i) for i in list]
list_str.sort()
print([int(i) for i in list_str])

ちょっと答えが違う

修正版です。
list = [0,1,2,3,4,5,6,7,8,9,10,11,12,20,21,100,101,201]
print(list)
print(sorted(list, key=lambda x:(str(x)[0],x)))

回答2

文字列にする ↓ 1文字目で比較 ↓ 文字数で比較 ↓ 辞書順 でしょうか?

回答3

coffee script
b=[0,1,2,3,4,5,6,7,8,9,10,11,12,20,21,100,101,201]
a=[0,1,10,11,12,100,101,2,20,21,201,3,4,5,6,7,8,9]

b.sort (a,b)->
  if a > b
    if a.toString()[0] > b.toString()[0]
      return 1
    if a.toString()[0] < b.toString()[0]
      return -1

    return 1
  if a < b
    if a.toString()[0] > b.toString()[0]
      return 1
    if a.toString()[0] < b.toString()[0]
      return -1

    return -1

  return 0

console.log b,"b"
console.log a,"a"

回答4

辞書順ソートじゃないんですよね、、自分も最初、辞書順ソートつくっちゃいました PHPだと
<?php
$num = [0,1,2,3,4,5,6,7,8,9,10,11,12,20,21,100,101,201];
usort($num, "testsort");
print_r($num);

function testsort($a, $b)
{
  $lead1 = substr($a, 0, 1);
  $lead2 = substr($b, 0, 1);

  if($lead1 == $lead2) {
    if($a > $b) {
      return 1;
    }
  } elseif($lead1 > $lead2) {
    return 1;
  }
  return -1;
}

回答5

Rubyでやってみました。
# 文字列の配列に変換します。
a = [0,1,2,3,4,5,6,7,8,9,10,11,12,20,21,100,101,201].map {|i| i.to_s }
=> ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "20", "21", "100", "101", "201"]

# 先頭文字でグルーピングします(先頭文字をキーとするハッシュができます)。
b = a.group_by {|item| item[0].chr }
=> {"0"=>["0"], "1"=>["1", "10", "11", "12", "100", "101"], "2"=>["2", "20", "21", "201"], "3"=>["3"], "4"=>["4"], "5"=>["5"], "6"=>["6"], "7"=>["7"], "8"=>["8"], "9"=>["9"]}

# 先頭文字の昇順でソートします。
c = Hash[b.sort_by {|k, v| k}]
=> {"0"=>["0"], "1"=>["1", "10", "11", "12", "100", "101"], "2"=>["2", "20", "21", "201"], "3"=>["3"], "4"=>["4"], "5"=>["5"], "6"=>["6"], "7"=>["7"], "8"=>["8"], "9"=>["9"]}

# 値を数値に変換し昇順でソートします(配列の配列ができます)。
d = c.map {|k,v| (v.map {|i| i.to_i }).sort}
=> [[0], [1, 10, 11, 12, 100, 101], [2, 20, 21, 201], [3], [4], [5], [6], [7], [8], [9]]

# 配列の配列を平坦化します。
d.flatten
=> [0, 1, 10, 11, 12, 100, 101, 2, 20, 21, 201, 3, 4, 5, 6, 7, 8, 9]

回答6

Javaでかきました
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] list = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 20, 21, 100, 101, 201 };
        List<Node> nodeList = new ArrayList<Node>();
        for (int i = 0; i < list.length; i++) {
            nodeList.add(new Node(list[i]));
        }
        Collections.sort(nodeList);
        for (int i = 0; i < list.length; i++) {
            System.out.println(nodeList.get(i));
        }
    }

}

class Node implements Comparable<Node> {
    private int num;
    private String str;

    public Node(int num) {
        this.num = num;
        this.str = String.valueOf(num);
    }

    @Override
    public int compareTo(Node n) {
        String a = this.str;
        String b = n.toString();
        int maxLength = a.length();
        if (maxLength > b.length()) {
            maxLength = b.length();
        }

        for (int i = 0; i < maxLength; i++) {
            if (a.charAt(i) > b.charAt(i)) {
                return 1;
            } else if (a.charAt(i) < b.charAt(i)) {
                return -1;
            }
        }
        if (a.length() < b.length()) {
            return -1;
        } else if (a.length() > b.length()) {
            return 1;
        }
        return 0;
    }

    @Override
    public String toString() {
        return this.str;
    }

    public int getInt() {
        return this.num;
    }
}

回答7

変数名が結構適当ですが・・・・・。 以下のことを行っています。
  1. 文字列比較で並べ替え
  2. 先頭の文字を見てグループ分け(0 | 1 …| 2 ….)
  3. グループごとに昇順ソート
  4. 連結
<?php
$numList = [0,1,2,3,4,5,6,7,8,9,10,11,12,20,21,100,101,201];
foreach($numList as $val) {
    $strList[] = (String)$val;
}

usort($strList, "compareStr");
$map = getStrFirstList($strList);
$num = [];

foreach($map as $key => $val) {
    for($i = 0; $i< count($map) ; $i++) {
        if($val == $i) {
            $num[$i][] = $key;
            asort($num[$i]);
        }
    }
}

foreach($num as $keys => $values) {
    foreach($values as $key => $val) {
        $sortList[] = $val;
    }
}

print_r($sortList);

function compareStr($a, $b) {
    return strcmp($a, $b);
}

function getStrFirstList($strList) {
    foreach($strList as $key => $val) {
        $tmp[$val] = substr($val, 0, 1);
    }

    return $tmp;
}
?>

回答8

悔しかったので家に帰った後で考えました。
# 数値のリストから文字列のリストに変換
raw_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 20, 21, 100, 101, 201]
str_list = [str(elem1) for elem1 in raw_list]

# 先頭の数値をキーとした配列の辞書に分ける、値を整数値に戻す
first_num_dict = {key[0]: [] for key in str_list}
for str_elem in str_list:
    first_num_dict[str_elem[0]].append(int(str_elem))

# それぞれの配列内でソート(=数値順にソート)した結果を順番に取り出し、配列を生成
result_list = [val for key in sorted(first_num_dict.keys()) for val in sorted(first_num_dict[key])]

print(result_list)

回答9

Swiftです。強制アンラップはいけないですが、、、
let list = [0, 1, 2, 4, 3, 5, 6, 7, 8, 9, 11, 10, 12, 20, 21, 100, 101, 201]

var listString: [String] = []

for num in list {
    listString.append(String(num))
}

let listSorted: [String] = listString.sorted(by: { (s1: String, s2: String) -> Bool in

    if s1[s1.startIndex] == s2[s2.startIndex] {
        return Int(s1)! < Int(s2)!
    }

    return s1[s1.startIndex] < s2[s2.startIndex]
})

print(listSorted)

1日で多様な言語で投稿ありました! 皆さんありがとうございます!

是非試しに他の言語でもやってみてください!

にょこた

PM(プロダクトマネージャー)目指して奮闘中、プログラムから、アーキテクト設計、サービス検討から、チームマネジメント、DevOps、いろいろやってます。

目次