Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,14 @@
"prerequisites": [],
"difficulty": 5
},
{
"slug": "say",
"name": "Say",
"uuid": "fe349bef-fa91-439a-bed2-1ac12c4ad5d1",
"practices": [],
"prerequisites": [],
"difficulty": 5
},
{
"slug": "simple-linked-list",
"name": "Simple Linked List",
Expand Down
12 changes: 12 additions & 0 deletions exercises/practice/say/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Instructions

Given a number, your task is to express it in English words exactly as your friend should say it out loud.
Yaʻqūb expects to use numbers from 0 up to 999,999,999,999.

Examples:

- 0 → zero
- 1 → one
- 12 → twelve
- 123 → one hundred twenty-three
- 1,234 → one thousand two hundred thirty-four
6 changes: 6 additions & 0 deletions exercises/practice/say/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Introduction

Your friend Yaʻqūb works the counter at the busiest deli in town, slicing, weighing, and wrapping orders for a never-ending line of hungry customers.
To keep things moving, each customer takes a numbered ticket when they arrive.

When it’s time to call the next person, Yaʻqūb reads their number out loud, always in full English words to make sure everyone hears it clearly.
19 changes: 19 additions & 0 deletions exercises/practice/say/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"BNAndras"
],
"files": {
"solution": [
"say.vim"
],
"test": [
"say.vader"
],
"example": [
".meta/example.vim"
]
},
"blurb": "Given a number from 0 to 999,999,999,999, spell out that number in English.",
"source": "A variation on the JavaRanch CattleDrive, Assignment 4",
"source_url": "https://web.archive.org/web/20240907035912/https://coderanch.com/wiki/718804"
}
78 changes: 78 additions & 0 deletions exercises/practice/say/.meta/example.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
function! Say(number) abort
if a:number < 0 || a:number > 999999999999
throw 'input out of range'
endif

if a:number == 0
return 'zero'
endif

let l:chunks = s:ChunksReversed(a:number)
let l:fragments = map(l:chunks, function('s:ToWords'))
let l:fragments = map(l:fragments, function('s:ApplyScale'))
let l:fragments = filter(l:fragments, '!empty(v:val)')
call reverse(l:fragments)
return join(l:fragments, ' ')
endfunction

function! s:ApplyScale(index, value) abort
if empty(a:value)
return
endif

if !a:index
return a:value
elseif a:index == 1
return a:value . ' thousand'
elseif a:index == 2
return a:value . ' million'
elseif a:index == 3
return a:value . ' billion'
endif
endfunction

function! s:ChunksReversed(str) abort
let l:result = []
let l:working = a:str

while len(l:working) > 0
call add(l:result, l:working[-3:])
let l:working = l:working[:-4]
endwhile

return l:result
endfunction

function! s:ToWords(index, chunk)
let l:words = []
if a:chunk < 20
call add(l:words, s:FirstTwentyNumbers[a:chunk])
elseif a:chunk < 100
let l:tens = s:WordsForTens[a:chunk / 10]
let l:ones = s:FirstTwentyNumbers[a:chunk % 10]
if !empty(l:ones)
call add(l:words, l:tens . '-' . l:ones)
else
call add(l:words, l:tens)
endif
else
let l:hundreds = s:FirstTwentyNumbers[a:chunk / 100]
let l:rest = s:ToWords(a:index, a:chunk % 100)
if !empty(l:rest)
call add(l:words, l:hundreds . ' hundred ' . l:rest)
else
call add(l:words, l:hundreds . ' hundred')
endif
endif

return join(l:words, ' ')
endfunction

let s:FirstTwentyNumbers = [
\ '','one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten',
\ 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'
\ ]

let s:WordsForTens = [
\ '', 'tens', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'
\ ]
67 changes: 67 additions & 0 deletions exercises/practice/say/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[5d22a120-ba0c-428c-bd25-8682235d83e8]
description = "zero"

[9b5eed77-dbf6-439d-b920-3f7eb58928f6]
description = "one"

[7c499be1-612e-4096-a5e1-43b2f719406d]
description = "fourteen"

[f541dd8e-f070-4329-92b4-b7ce2fcf06b4]
description = "twenty"

[d78601eb-4a84-4bfa-bf0e-665aeb8abe94]
description = "twenty-two"

[f010d4ca-12c9-44e9-803a-27789841adb1]
description = "thirty"

[738ce12d-ee5c-4dfb-ad26-534753a98327]
description = "ninety-nine"

[e417d452-129e-4056-bd5b-6eb1df334dce]
description = "one hundred"

[d6924f30-80ba-4597-acf6-ea3f16269da8]
description = "one hundred twenty-three"

[2f061132-54bc-4fd4-b5df-0a3b778959b9]
description = "two hundred"

[feed6627-5387-4d38-9692-87c0dbc55c33]
description = "nine hundred ninety-nine"

[3d83da89-a372-46d3-b10d-de0c792432b3]
description = "one thousand"

[865af898-1d5b-495f-8ff0-2f06d3c73709]
description = "one thousand two hundred thirty-four"

[b6a3f442-266e-47a3-835d-7f8a35f6cf7f]
description = "one million"

[2cea9303-e77e-4212-b8ff-c39f1978fc70]
description = "one million two thousand three hundred forty-five"

[3e240eeb-f564-4b80-9421-db123f66a38f]
description = "one billion"

[9a43fed1-c875-4710-8286-5065d73b8a9e]
description = "a big number"

[49a6a17b-084e-423e-994d-a87c0ecc05ef]
description = "numbers below zero are out of range"

[4d6492eb-5853-4d16-9d34-b0f61b261fd9]
description = "numbers above 999,999,999,999 are out of range"
96 changes: 96 additions & 0 deletions exercises/practice/say/say.vader
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
Execute (zero):
let g:number = 0
let g:expected = "zero"
AssertEqual g:expected, Say(g:number)

Execute (one):
let g:number = 1
let g:expected = "one"
AssertEqual g:expected, Say(g:number)

Execute (fourteen):
let g:number = 14
let g:expected = "fourteen"
AssertEqual g:expected, Say(g:number)

Execute (twenty):
let g:number = 20
let g:expected = "twenty"
AssertEqual g:expected, Say(g:number)

Execute (twenty-two):
let g:number = 22
let g:expected = "twenty-two"
AssertEqual g:expected, Say(g:number)

Execute (thirty):
let g:number = 30
let g:expected = "thirty"
AssertEqual g:expected, Say(g:number)

Execute (ninety-nine):
let g:number = 99
let g:expected = "ninety-nine"
AssertEqual g:expected, Say(g:number)

Execute (one hundred):
let g:number = 100
let g:expected = "one hundred"
AssertEqual g:expected, Say(g:number)

Execute (one hundred twenty-three):
let g:number = 123
let g:expected = "one hundred twenty-three"
AssertEqual g:expected, Say(g:number)

Execute (two hundred):
let g:number = 200
let g:expected = "two hundred"
AssertEqual g:expected, Say(g:number)

Execute (nine hundred ninety-nine):
let g:number = 999
let g:expected = "nine hundred ninety-nine"
AssertEqual g:expected, Say(g:number)

Execute (one thousand):
let g:number = 1000
let g:expected = "one thousand"
AssertEqual g:expected, Say(g:number)

Execute (one thousand two hundred thirty-four):
let g:number = 1234
let g:expected = "one thousand two hundred thirty-four"
AssertEqual g:expected, Say(g:number)

Execute (one million):
let g:number = 1000000
let g:expected = "one million"
AssertEqual g:expected, Say(g:number)

Execute (one million two thousand three hundred forty-five):
let g:number = 1002345
let g:expected = "one million two thousand three hundred forty-five"
AssertEqual g:expected, Say(g:number)

Execute (one billion):
let g:number = 1000000000
let g:expected = "one billion"
AssertEqual g:expected, Say(g:number)

Execute (a big number):
let g:number = 987654321123
let g:expected = "nine hundred eighty-seven billion six hundred fifty-four million three hundred twenty-one thousand one hundred twenty-three"
AssertEqual g:expected, Say(g:number)

Execute (numbers below zero are out of range):
let g:number = -1
let g:expected = "input out of range"
AssertThrows call Say(g:number)
AssertEqual g:expected, g:vader_exception

Execute (numbers above 999,999,999,999 are out of range):
let g:number = 1000000000000
let g:expected = "input out of range"
AssertThrows call Say(g:number)
AssertEqual g:expected, g:vader_exception
14 changes: 14 additions & 0 deletions exercises/practice/say/say.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"
" Say converts a numeric value between 0 and 999,999,999,999 into its spoken
" English equivalent.
"
" Examples:
" :echo Say(0)
" zero
"
" :echo Say(123)
" one hundred twenty-three
"
function! Say(number) abort
" your code goes here
endfunction