第155回【Python】数字のみの出力、昇順ソート出力、文字と整数の組のソート

現在取り組んでいるのは、paiza ラーニング問題集「B ランクレベルアップメニュー」になります。

はじめに

猫とキャンプと野球観戦と AWS が大好きな旦那、LeoSaki です。モフモフしたい。

Python をゼロから勉強してみよう、のコーナー 155 回目です。

リモートの環境が整っていないなかでリモートを行うのは、長期的に見て愚策だと思っています。実際、リモートを行っている別部署は 3 年経過して状況が良いとは言えないと感じています。大金を投じて環境を整えるか、リモートを解除するか、そろそろ選択の時だと思うのだけれど。

それでは、今日も頑張ってみようと思います。

今回取り組む内容について

以下は、前回までに取り組んだ問題とまったく同じなので、飛ばします。
コードは数書いてナンボとかカッコつけたこと書いてましたが、あまりにも多いので挫折しました。

STEP: 1 インクリメント

数字のみの出力 (paizaランク D 相当)

1行目に行数を表す整数 n、続く n 行で m 個の「文字」と「整数」の組が空白区切りで入力されます。
n 個の整数だけをそのまま順に出力してください。

n
S_1 D_1
S_2 D_2
...
S_n D_n

期待する出力

n 個の整数を順に改行区切りで出力してください。
最後は改行し、余計な文字、空行を含んではいけません。


すべてのテストケースにおいて、以下の条件をみたします。

・1 ≦ n ≦ 10,000
・-10,000 ≦ D_i ≦ 10,000 (ただし、1 ≦i ≦ n)
・S_iは1つの半角英文字


入力例

4
S 1
F 2
E 5
Y 6

出力例

1
2
5
6

何がしたいのかはよくわからないが、「整数」だけを取り出す作業を行う。

Python
n = int(input())
for _ in range(n):
    s,d = input().split()
    print(int(d))

模範解答では、「整数」として出力していないのだけれど。print(d) だけ書くのは、問題の意図に合わない気がする。

VBA
Sub sort_asc_1()

    N = Cells(1, 1)
    For i = 1 To N
        sd = Split(Cells(i + 1, 1), " ")
        Debug.Print Val(sd(1))
    Next
    
End Sub

昇順ソート出力 (paizaランク D 相当)

1行目で整数 n が与えられ、2行目で n 個の整数が与えられます。
n 個の整数を昇順に出力してください。

n
a_1 a_2 ... a_n

期待する出力

a_1 から a_n の整数を昇順に並び替えて、出力してください。
最後は改行し、余計な文字、空行を含んではいけません。


すべてのテストケースにおいて、以下の条件をみたします。

1 ≦ n ≦ 100
-3,000,000 ≦ a_i ≦ 3,000,000 (ただし、1 ≦ i ≦ n)


入力例

8
90 777 8888 121 333 4 29 2

出力例

2
4
29
90
121
333
777
8888

並び替えかぁ。VBA ではちょっと面倒なんだよな。やってみる。

Python
n = int(input())
li = [int(x) for x in input().split()]
for v in sorted(li):
    print(v)
VBA
Sub sort_asc_2()

    N = Cells(1, 1)
    tmp = Split(Cells(2, 1), " ")
    
    Dim a() As Variant
    ReDim a(N - 1)
    
    For i = 0 To N - 1
        a(i) = Val(tmp(i))
    Next
    
    Call QuickSort(a, LBound(a), UBound(a))
    
    For Each v In a
        Debug.Print v
    Next
    
End Sub

Private Sub QuickSort(ByRef argAry() As Variant, ByVal lngMin As Long, ByVal lngMax As Long)
 
    Dim i As Long
    Dim j As Long
    Dim vBase As Variant
    Dim vSwap As Variant
    vBase = argAry(Int((lngMin + lngMax) / 2))
    i = lngMin
    j = lngMax
    Do
        Do While argAry(i) < vBase
            i = i + 1
        Loop
        Do While argAry(j) > vBase
            j = j - 1
        Loop
        If i >= j Then Exit Do
        vSwap = argAry(i)
        argAry(i) = argAry(j)
        argAry(j) = vSwap
        i = i + 1
        j = j - 1
    Loop
    If (lngMin < i - 1) Then
        Call QuickSort(argAry, lngMin, i - 1)
    End If
    If (lngMax > j + 1) Then
        Call QuickSort(argAry, j + 1, lngMax)
    End If
     
End Sub

文字と整数の組のソート (paizaランク C 相当)

1行目に行数を表す整数 n、続く n 行の各行で「文字」と「整数」の組が空白区切りで入力されます。
n 個の組を、「整数」の値で昇順に並べ変え、「文字」を出力してください。

n
S_1 D_1
S_2 D_2
...
S_i D_i
...
S_n D_n

S_i は「文字」で、D_i は「整数」です。
入力される文字 S_i は、同じ文字が複数入力されることはなく、整数 D_i も同様です。


期待する出力

n 個の組を、「整数」の値で昇順に並べ変え、「文字列」を1行ずつ出力してください。


すべてのテストケースにおいて、以下の条件をみたします。

・1 ≦ n ≦ 100
・-10,000 ≦ D_i ≦ 10,000
・S_iは半角英文字1文字
・iとjが異なるなら、D_iとD_jは異なる
・iとjが異なるなら、S_iとS_jは異なる


入力例

3
G 0
S 3
E -2

出力例

E
G
S

組み合わせでの並び替えかぁ。VBA ではかなり面倒なんだよな。やってみる。

Python
n = int(input())

li = [None] * n
for i in range(n):
    s,d = input().split()
    d = int(d)
    li[i] = (d,s)

for d,s in sorted(li):
    print(s)
VBA
Sub sort_asc_9()

    N = Cells(1, 1)
    
    Dim dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    
    For i = 1 To N
        tmp = Split(Cells(i + 1, 1), " ")
        dic.Add Val(tmp(1)), tmp(0)
    Next

    arrKeys = dic.Keys
    
    Dim arrList()
    ReDim arrList(dic.Count - 1, 1)
    
    For i = LBound(arrKeys) To UBound(arrKeys)
        arrList(i, 0) = arrKeys(i)
        arrList(i, 1) = dic(arrKeys(i))
    Next
    
    Call QuickSort_dic(arrList, LBound(arrList, 1), UBound(arrList, 1))
    
    dic.RemoveAll
    
    For i = LBound(arrList) To UBound(arrList)
        dic.Add arrList(i, 0), arrList(i, 1)
    Next
    
    For Each v In dic
        Debug.Print dic(v)
    Next
    
End Sub

Private Sub QuickSort_dic(ByRef arrList() As Variant, ByVal minIDX As Long, ByVal maxIDX As Long)
 
    Dim valMEDIAN As Variant
    Dim arrTEMP() As Variant
    Dim i As Long
    Dim j As Long
     
    'ソート範囲の上下限を設定
    i = minIDX
    j = maxIDX
     
    '基準値としてインデックスの中央値のデータを使用します。
    valMEDIAN = arrList(Int((minIDX + maxIDX) / 2), 0)
 
    Do
        'インデックスの小さい方から値を比較していく
        Do While arrList(i, 0) < valMEDIAN
            i = i + 1
        Loop
         
        'インデックスの大きい方から値を比較していく
        Do While arrList(j, 0) > valMEDIAN
            j = j - 1
        Loop
         
        'インデックスが逆転したらループ抜け
        If i >= j Then Exit Do
         
        '配列を定義
        ReDim arrTEMP(0, 1)
         
        '配列内のデータの入れ替え1
        arrTEMP(0, 0) = arrList(i, 0)
        arrList(i, 0) = arrList(j, 0)
        arrList(j, 0) = arrTEMP(0, 0)
         
        '配列内のデータの入れ替え2
        arrTEMP(0, 1) = arrList(i, 1)
        arrList(i, 1) = arrList(j, 1)
        arrList(j, 1) = arrTEMP(0, 1)
         
        '配列の初期化
        Erase arrTEMP
         
        'インデックスの加減算
        i = i + 1
        j = j - 1
    Loop
     
    '再帰でソートが完了するまで繰り返し
    If (minIDX < i - 1) Then Call QuickSort_dic(arrList, minIDX, i - 1)
    If (maxIDX > j + 1) Then Call QuickSort_dic(arrList, j + 1, maxIDX)
     
End Sub

最後に

Python では数行のコードが、VBA ではなかなかの力作に。VBA だけでなく、模範解答にある、C++ や PHP でも Python ほど簡潔には書けない。なんとも便利。

VBA のクイックソートは早いのだけれど、面倒だ。連想配列用に配列用、それぞれに文字で並べ替え用、数値で並べ替え用、さらに昇順用、降順用と、バリエーション豊富に用意しておかなければならない。

引き続き、よろしくお願いいたします!

PythonPython,paiza,学習

Posted by LeoSaki