challenge 文字列のセンタリング

文字列を指定のカラム幅にセンタリング配置する関数を示してください。文字列の長さが指定した幅より長い場合には文字列の両端をできるだけ均等に切り落して指定幅に収めてください。1文字は1カラムに収まるものと仮定してかまいません。

Posted feedbacks - Other

(width.odd? xor self.odd?) のときに、余計に1文字削ってしまうと思います。

1
p "0123456789".centered(3)  => "45"

Mac OS X (PowerPC 32bit) アセンブリで。strcenter.o をリンクして使います。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
;; ------------------------------------------------
;; strcenter.s for Mac OS X (PowerPC 32bit)
;; % as -o strcenter.o strcenter.s
;; ------------------------------------------------

        .machine ppc
        .globl  _strcenter

;; char *strcenter(char *dest, const char *s, size_t width)
;;
;; r3: char *dest
;; r4: const char *s
;; r5: size_t width
;;
;; r7:  文字列 s のサイズ
;; r8:  文字列の前のスペースのサイズ
;; r9:  文字列の後のスペースのサイズ
;; r10: スペースのASCIIコード
;; r11: r3 のコピー
;; r12: r4 のコピー
;; 
_strcenter:
        ;; 初期化
        li      r7, 0
        li      r10, 32         ; ' '
        mr      r11, r3
        mr      r12, r4
        b       _strlen

_init_sizes:
        ;; 基準となるスペースのサイズ
        sub     r2, r5, r7      ; r2 = width - strlen(s)
        li      r0, 2
        divw    r2, r2, r0      ; r2 = r2 / 2

        ;; 余り
        sub     r0, r5, r7      ; r0 = width - strlen(s)
        andi.   r0, r0, 1

        ;; 前後のスペースのサイズを決定、コピー
        add     r8, r2, r0      ; 余りがあれば前のスペースに追加
        addi    r9, r2, 0

        ;; 基準のスペースのサイズが負の場合
        cmpi    cr7, r2, 0
        blt     cr7, _shorten_strcenter

;; 前のスペースをコピー
_copy_former_spaces:
        stb     r10, 0(r11)
        addi    r11, r11, 1
        subi    r8, r8, 1
        cmpli   cr7, r8, 0
        bgt     cr7, _copy_former_spaces

;; 文字列をコピー
_copy_str:
        lbz     r0, 0(r12)
        stb     r0, 0(r11)
        addi    r11, r11, 1
        addi    r12, r12, 1
        subi    r7, r7, 1
        cmpli   cr7, r7, 0
        bgt     cr7, _copy_str

;; 後のスペースをコピー
_copy_latter_spaces:
        stb     r10, 0(r11)
        addi    r11, r11, 1
        subi    r9, r9, 1
        cmpli   cr7, r9, 0
        bgt     cr7, _copy_latter_spaces

;; 終端をコピーして終了
_end_strcenter:
        li      r0, 0
        stb     r0, 0(r11)
        blr                     ; 関数を終了

;; 文字列の前後をカットしてコピー
_shorten_strcenter:
        sub     r12, r12, r8    ; 文字列の前半をカット
        add     r7, r7, r8
        add     r7, r7, r9      ; 文字列の後半をカット

_copy_shorten_str:
        lbz     r0, 0(r12)
        stb     r0, 0(r11)
        addi    r11, r11, 1
        addi    r12, r12, 1
        subi    r7, r7, 1
        cmpli   cr7, r7, 0
        bgt     cr7, _copy_shorten_str
        b       _end_strcenter

_strlen:
        mr      r2, r4
        li      r7, 0
        
__strlen:
        lbz     r0, 0(r2)       ; 1文字レジスタに移す
        cmpli   cr7, r0, 0
        beq     cr7, _init_sizes
        addi    r2, r2, 1
        addi    r7, r7, 1
        b       __strlen

Index

Feed

Other

Link

Pathtraq

loading...