Four is the number of letters in the ...: Difference between revisions

Content added Content deleted
m (Rust - reformatted with rustfmt)
Line 1,119: Line 1,119:
Length of sentence = 70995756
Length of sentence = 70995756
</pre>
</pre>

=={{header|Nim}}==
<lang Nim>import strutils, strformat, tables

####################################################################################################
# Cardinal and ordinal strings.

const

Small = ["zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
"ten", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]

Tens = ["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]

Illions = ["", " thousand", " million", " billion", " trillion", " quadrillion", " quintillion"]

IrregularOrdinals = {"one": "first", "two": "second", "three": "third", "five": "fifth",
"eight": "eighth", "nine": "ninth", "twelve": "twelfth"}.toTable()

#---------------------------------------------------------------------------------------------------

func spellCardinal(n: int64): string =
## Spell an integer as a cardinal.

var n = n

if n < 0:
result = "negative "
n = -n

if n < 20:
result &= Small[n]

elif n < 100:
result &= Tens[n div 10]
let m = n mod 10
if m != 0: result &= '-' & Small[m]

elif n < 1000:
result &= Small[n div 100] & " hundred"
let m = n mod 100
if m != 0: result &= ' ' & m.spellCardinal()

else:
# Work from right to left.
var sx = ""
var i = 0
while n > 0:
let m = n mod 1000
n = n div 1000
if m != 0:
var ix = m.spellCardinal() & Illions[i]
if sx.len > 0: ix &= " " & sx
sx = ix
inc i
result &= sx

#---------------------------------------------------------------------------------------------------

func spellOrdinal(n: int64): string =
## Spell an integer as an ordinal.

result = n.spellCardinal()
var parts = result.rsplit({' ', '-'}, maxsplit = 1)
let tail = parts[^1]
if tail in IrregularOrdinals:
result[^tail.len..^1] = IrregularOrdinals[tail]
elif tail.endsWith('y'):
result[^1..^1]= "ieth"
else:
result &= "th"


####################################################################################################
# Sentence building.

type Sentence = seq[string]

#---------------------------------------------------------------------------------------------------

iterator words(sentence: var Sentence): tuple[idx: int; word: string] =
## Yield the successive words of the sentence with their index.

yield (0, "Four")
var idx = 1
var last = 0
while true:
yield (idx, sentence[idx])
inc idx
if idx == sentence.len:
inc last
sentence.add([sentence[last].count(Letters).spellCardinal(), "in", "the"])
# For the position, we need to split the ordinal as it may contain spaces.
sentence.add(((last + 1).spellOrdinal() & ',').splitWhitespace())

#---------------------------------------------------------------------------------------------------

iterator letterCounts(sentence: var Sentence): tuple[idx: int; word: string; count: int] =
## Secondary iterator used to yield the number of letters in addition to the index and the word.

for i, word in sentence.words():
yield (i, word, word.count(Letters))


####################################################################################################
# Drivers.

# Constant to initialize the sentence.
const Init = "Four is the number of letters in the first word of this sentence,".splitWhitespace()

#---------------------------------------------------------------------------------------------------

proc displayLetterCounts(pos: Positive) =
## Display the number of letters of the word at position "pos".

var sentence = Init
echo fmt"Number of letters in first {pos} words in the sequence:"
var valcount = 0 # Number of values displayed in the current line.
var length = 0

for i, word, letterCount in sentence.letterCounts():
if i == pos:
# Terminated.
dec length # Adjust space count.
echo ""
break

stdout.write ($letterCount).align(3)
inc valcount
inc length, word.len + 1 # +1 for space.

if valcount == 12:
# Terminate line.
echo ""
valcount = 0

echo fmt"Sentence length: {length}"

#---------------------------------------------------------------------------------------------------

proc displayWord(pos: Positive) =
## Display the word at position "pos".

var sentence = Init
let idx = pos - 1
var length = 0
for i, word in sentence.words():
length += word.len + 1
if i == idx:
dec length # Adjust space count.
echo fmt"Word {pos} is ""{word}"" with {word.count(Letters)} letters."
echo fmt"Length of sequence: {length}"
break

#———————————————————————————————————————————————————————————————————————————————————————————————————

displayLetterCounts(201)
for n in [1_000, 10_000, 100_000, 1_000_000, 10_000_000]:
echo ""
displayWord(n)</lang>

{{out}}
<pre>Number of letters in first 201 words in the sequence:
4 2 3 6 2 7 2 3 5 4 2 4
8 3 2 3 6 5 2 3 5 3 2 3
6 3 2 3 5 5 2 3 5 3 2 3
7 5 2 3 6 4 2 3 5 4 2 3
5 3 2 3 8 4 2 3 7 5 2 3
10 5 2 3 10 3 2 3 9 5 2 3
9 3 2 3 11 4 2 3 10 3 2 3
10 5 2 3 9 4 2 3 11 5 2 3
12 3 2 3 11 5 2 3 12 3 2 3
11 5 2 3 11 3 2 3 13 5 2 3
12 4 2 3 11 4 2 3 9 3 2 3
11 5 2 3 12 4 2 3 11 5 2 3
12 3 2 3 11 5 2 3 11 5 2 3
13 4 2 3 12 3 2 3 11 5 2 3
8 3 2 3 10 4 2 3 11 3 2 3
10 5 2 3 11 4 2 3 10 4 2 3
10 3 2 3 12 5 2 3 11
Sentence length: 1203

Word 1000 is "in" with 2 letters.
Length of sequence: 6249

Word 10000 is "in" with 2 letters.
Length of sequence: 64097

Word 100000 is "one" with 3 letters.
Length of sequence: 659455

Word 1000000 is "the" with 3 letters.
Length of sequence: 7113560

Word 10000000 is "thousand" with 8 letters.
Length of sequence: 70995729</pre>


=={{header|Perl}}==
=={{header|Perl}}==