Base-16 representation: Difference between revisions
Content added Content deleted
(→{{header|Haskell}}: Added a Haskell version) |
(→{{header|JavaScript}}: Added a JavaScript version.) |
||
Line 908: | Line 908: | ||
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
||
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 |
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 |
||
500</pre> |
|||
=={{header|JavaScript}}== |
|||
<lang javascript>(() => { |
|||
"use strict"; |
|||
// --- ANY ALPHA DIGITS REQUIRED IN HEXADECIMAL ? ---- |
|||
// p :: Int -> Bool |
|||
const p = n => |
|||
// True if a hexadecimal representation of the |
|||
// integer n requires any digits above 9. |
|||
9 < n && ( |
|||
9 < n % 16 || p( |
|||
Math.trunc(n / 16) |
|||
) |
|||
); |
|||
// ---------------------- TEST ----------------------- |
|||
// main :: IO () |
|||
const main = () => { |
|||
const |
|||
upperLimit = 500, |
|||
xs = enumFromTo(0)(upperLimit) |
|||
.flatMap( |
|||
x => p(x) ? [ |
|||
`${x}` |
|||
] : [] |
|||
); |
|||
return [ |
|||
`${xs.length} matches up to ${upperLimit}:\n`, |
|||
table(" ")(justifyRight)( |
|||
chunksOf(6)(xs) |
|||
) |
|||
].join("\n"); |
|||
}; |
|||
// --------------------- DISPLAY --------------------- |
|||
// table :: String -> |
|||
// (Int -> Char -> String -> String) -> |
|||
// [[String]] -> String |
|||
const table = gap => |
|||
// A tabulation of rows of string values, |
|||
// with a specified gap between columns, |
|||
// and choice of cell alignment function |
|||
// (justifyLeft | center | justifyRight) |
|||
alignment => rows => { |
|||
const |
|||
colWidths = transpose(rows).map( |
|||
row => maximum(row.map(x => x.length)) |
|||
); |
|||
return rows.map( |
|||
compose( |
|||
intercalate(gap), |
|||
zipWith( |
|||
flip(alignment)(" ") |
|||
)(colWidths) |
|||
) |
|||
).join("\n"); |
|||
}; |
|||
// --------------------- GENERIC --------------------- |
|||
// chunksOf :: Int -> [a] -> [[a]] |
|||
const chunksOf = n => { |
|||
// xs split into sublists of length n. |
|||
// The last sublist will be short if n |
|||
// does not evenly divide the length of xs . |
|||
const go = xs => { |
|||
const chunk = xs.slice(0, n); |
|||
return 0 < chunk.length ? ( |
|||
[chunk].concat( |
|||
go(xs.slice(n)) |
|||
) |
|||
) : []; |
|||
}; |
|||
return go; |
|||
}; |
|||
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c |
|||
const compose = (...fs) => |
|||
// A function defined by the right-to-left |
|||
// composition of all the functions in fs. |
|||
fs.reduce( |
|||
(f, g) => x => f(g(x)), |
|||
x => x |
|||
); |
|||
// enumFromTo :: Int -> Int -> [Int] |
|||
const enumFromTo = m => |
|||
n => Array.from({ |
|||
length: 1 + n - m |
|||
}, (_, i) => m + i); |
|||
// flip :: (a -> b -> c) -> b -> a -> c |
|||
const flip = op => |
|||
// The binary function op with |
|||
// its arguments reversed. |
|||
1 < op.length ? ( |
|||
(a, b) => op(b, a) |
|||
) : (x => y => op(y)(x)); |
|||
// intercalateS :: String -> [String] -> String |
|||
const intercalate = s => |
|||
// The concatenation of xs |
|||
// interspersed with copies of s. |
|||
xs => xs.join(s); |
|||
// justifyRight :: Int -> Char -> String -> String |
|||
const justifyRight = n => |
|||
// The string s, preceded by enough padding (with |
|||
// the character c) to reach the string length n. |
|||
c => s => Boolean(s) ? ( |
|||
s.padStart(n, c) |
|||
) : ""; |
|||
// maximum :: Ord a => [a] -> a |
|||
const maximum = xs => ( |
|||
// The largest value in a non-empty list. |
|||
ys => 0 < ys.length ? ( |
|||
ys.slice(1).reduce( |
|||
(a, y) => y > a ? ( |
|||
y |
|||
) : a, ys[0] |
|||
) |
|||
) : undefined |
|||
)(xs); |
|||
// transpose :: [[a]] -> [[a]] |
|||
const transpose = rows => { |
|||
// If any rows are shorter than those that follow, |
|||
// their elements are skipped: |
|||
// > transpose [[10,11],[20],[],[30,31,32]] |
|||
// == [[10,20,30],[11,31],[32]] |
|||
const go = xss => |
|||
0 < xss.length ? (() => { |
|||
const |
|||
h = xss[0], |
|||
t = xss.slice(1); |
|||
return 0 < h.length ? [ |
|||
[h[0]].concat(t.reduce( |
|||
(a, xs) => a.concat( |
|||
0 < xs.length ? ( |
|||
[xs[0]] |
|||
) : [] |
|||
), |
|||
[] |
|||
)) |
|||
].concat(go([h.slice(1)].concat( |
|||
t.map(xs => xs.slice(1)) |
|||
))) : go(t); |
|||
})() : []; |
|||
return go(rows); |
|||
}; |
|||
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] |
|||
const zipWith = f => |
|||
// A list constructed by zipping with a |
|||
// custom function, rather than with the |
|||
// default tuple constructor. |
|||
xs => ys => xs.map( |
|||
(x, i) => f(x)(ys[i]) |
|||
).slice( |
|||
0, Math.min(xs.length, ys.length) |
|||
); |
|||
// MAIN --- |
|||
return main(); |
|||
})();</lang> |
|||
{{Out}} |
|||
<pre>301 matches up to 500: |
|||
10 11 12 13 14 15 |
|||
26 27 28 29 30 31 |
|||
42 43 44 45 46 47 |
|||
58 59 60 61 62 63 |
|||
74 75 76 77 78 79 |
|||
90 91 92 93 94 95 |
|||
106 107 108 109 110 111 |
|||
122 123 124 125 126 127 |
|||
138 139 140 141 142 143 |
|||
154 155 156 157 158 159 |
|||
160 161 162 163 164 165 |
|||
166 167 168 169 170 171 |
|||
172 173 174 175 176 177 |
|||
178 179 180 181 182 183 |
|||
184 185 186 187 188 189 |
|||
190 191 192 193 194 195 |
|||
196 197 198 199 200 201 |
|||
202 203 204 205 206 207 |
|||
208 209 210 211 212 213 |
|||
214 215 216 217 218 219 |
|||
220 221 222 223 224 225 |
|||
226 227 228 229 230 231 |
|||
232 233 234 235 236 237 |
|||
238 239 240 241 242 243 |
|||
244 245 246 247 248 249 |
|||
250 251 252 253 254 255 |
|||
266 267 268 269 270 271 |
|||
282 283 284 285 286 287 |
|||
298 299 300 301 302 303 |
|||
314 315 316 317 318 319 |
|||
330 331 332 333 334 335 |
|||
346 347 348 349 350 351 |
|||
362 363 364 365 366 367 |
|||
378 379 380 381 382 383 |
|||
394 395 396 397 398 399 |
|||
410 411 412 413 414 415 |
|||
416 417 418 419 420 421 |
|||
422 423 424 425 426 427 |
|||
428 429 430 431 432 433 |
|||
434 435 436 437 438 439 |
|||
440 441 442 443 444 445 |
|||
446 447 448 449 450 451 |
|||
452 453 454 455 456 457 |
|||
458 459 460 461 462 463 |
|||
464 465 466 467 468 469 |
|||
470 471 472 473 474 475 |
|||
476 477 478 479 480 481 |
|||
482 483 484 485 486 487 |
|||
488 489 490 491 492 493 |
|||
494 495 496 497 498 499 |
|||
500</pre> |
500</pre> |
||