aboutsummaryrefslogtreecommitdiff
path: root/challenge-101/abigail/node/ch-1.js
blob: cd5f7c875c69abb72bd3a7f1668eab2862adf226 (plain)
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
#!/usr/local/bin/node

//
// See ../README.md
//

//
// Run as: node ch-1.js < input-file
//

let RIGHT = 0
let UP    = 1
let LEFT  = 2
let DOWN  = 3

require ('readline')
. createInterface ({input: process . stdin})   
. on ('line', _ => main (_))
;

let printf = require ('printf')


function main (_) {
    let elements = _ . split (/\s+/)

    //
    // Calculate the optimal height and width
    //
    let n      = elements . length
    let height = Math . floor (Math . sqrt (n))
    for (;n % height;) {
        height --
    }
    let width = n / height

    //
    // Initialize a matrix to fill in
    //
    let matrix    = Array ()
    for (i = 0; i < height; i ++) {
        matrix [i] = Array ()
    }

    //
    // Fill in the matrix, starting from the bottom left
    //
    let min_x     = 0
    let max_x     = height - 1
    let min_y     = 0
    let max_y     = width  - 1
    let x         = max_x
    let y         = min_y
    let direction = RIGHT

    elements . forEach (element => {
        matrix [x] [y] = element
        let turn = 0
        if (direction == RIGHT) {
            if   (y >= max_y) {turn = 1; x --; max_x --}
            else {y ++}
        }
        if (direction == UP) {
            if   (x <= min_y) {turn = 1; y --; max_y --}
            else {x --}
        }
        if (direction == LEFT) {
            if   (y <= min_y) {turn = 1; x ++; min_x ++}
            else {y --}
        }
        if (direction == DOWN) {
            if   (x >= max_x) {turn = 1; y ++; min_y ++}
            else {x ++}
        }

        if (turn) {
            direction ++
            direction %= 4
        }
    })

    //
    // Calculate the width of each column
    //
    let widths = Array ()
    for (y = 0; y < width; y ++) {
        let max = 0
        for (x = 0; x < height; x ++) {
            if (max < matrix [x] [y] . length) {
                max = matrix [x] [y] . length
            }
        }
        widths [y] = max
    }

    //
    // Print the matrix
    //
    matrix . forEach (row => {
        row . forEach ((element, y) => {
            let format = "%s%" + widths [y] + "s"
            printf (process . stdout, format, y ? " " : "", element)
        })
        process . stdout . write ("\n")
    })
}