I have a checkmate in one hundred seventeen moves.

Discussion of chess software programming and technical issues.

Moderator: Ras

User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

I have a checkmate in one hundred seventeen moves.

Post by sje »

Consider:

"I have a checkmate in 117 moves."

vs

"I have a checkmate in one hundred seventeen moves."

You'd rather have your program output the latter instead of the former. And if you are coding in C++, I've got something that will help.

Spell.h:

Code: Select all

#ifndef IncludeSpell
#define IncludeSpell

typedef   signed int si;
typedef unsigned int ui;

typedef   signed long long int si64;
typedef unsigned long long int ui64;

std::string SpellCardinalDuo(const ui value);
std::string SpellCardinalTriad(const ui value);

std::string SpellCardinalUi64(const ui64 value);
std::string SpellCardinalSi64(const si64 value);

#endif
Spell.cpp:

Code: Select all

#include <sstream>

#include "Spell.h"

static const char *units[10] =
{
  "zero",
  "one",
  "two",
  "three",
  "four",
  "five",
  "six",
  "seven",
  "eight",
  "nine"
};

static const char *teens[10] =
{
  "ten",
  "eleven",
  "twelve",
  "thirteen",
  "fourteen",
  "fifteen",
  "sixteen",
  "seventeen",
  "eighteen",
  "nineteen"
};

static const char *decades[10] =
{
  "zero",
  "ten",
  "twenty",
  "thirty",
  "forty",
  "fifty",
  "sixty",
  "seventy",
  "eighty",
  "ninety"
};

std::string SpellCardinalDuo(const ui value)
{
  std::ostringstream oss;

  if (value >= 20)
  {
    const ui d0 = value % 10;

    oss << decades[value / 10]; if (d0 != 0) oss << '-' << units[d0];
  }
  else
  {
    if (value >= 10) oss << teens[value - 10]; else oss << units[value];
  };
  return oss.str();
}

std::string SpellCardinalTriad(const ui value)
{
  std::ostringstream oss;
  const ui d2 = value / 100;

  if (d2 > 0)
  {
    const ui residue = value % 100;

    oss << units[d2] << ' ' << "hundred";
    if (residue > 0) oss << ' ' << SpellCardinalDuo(residue);
  }
  else
    oss << SpellCardinalDuo(value);
  return oss.str();
}

std::string SpellCardinalUi64(const ui64 value)
{
  std::ostringstream oss;
  ui64 residue = value;
  bool needspace = false;
  const ui64 t3  =       1000;
  const ui64 t6  = t3  * 1000;
  const ui64 t9  = t6  * 1000;
  const ui64 t12 = t9  * 1000;
  const ui64 t15 = t12 * 1000;
  const ui64 t18 = t15 * 1000;

  if (residue >= t18)
  {
    const ui triad = residue / t18;

    if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " quintillion";
    residue -= triad * t18; needspace = (residue != 0);
  };

  if (residue >= t15)
  {
    const ui triad = residue / t15;

    if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " quadrillion";
    residue -= triad * t15; needspace = (residue != 0);
  };

  if (residue >= t12)
  {
    const ui triad = residue / t12;

    if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " trillion";
    residue -= triad * t12; needspace = (residue != 0);
  };

  if (residue >= t9)
  {
    const ui triad = residue / t9;

    if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " billion";
    residue -= triad * t9; needspace = (residue != 0);
  };

  if (residue >= t6)
  {
    const ui triad = residue / t6;

    if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " million";
    residue -= triad * t6; needspace = (residue != 0);
  };

  if (residue >= t3)
  {
    const ui triad = residue / t3;

    if (needspace) oss << ' '; oss << SpellCardinalTriad(triad) << " thousand";
    residue -= triad * t3; needspace = (residue != 0);
  };

  if ((residue == value) || needspace)
  {
    const ui triad = residue;

    if (needspace) oss << ' '; oss << SpellCardinalTriad(triad);
  };

  return oss.str();
}

std::string SpellCardinalSi64(const si64 value)
{
  std::ostringstream oss;

  if (value < 0)
    oss << "minus " << SpellCardinalUi64((ui64) -value);
  else
    oss << SpellCardinalUi64((ui64) value);
  return oss.str();
}
User avatar
Zach Wegner
Posts: 1922
Joined: Thu Mar 09, 2006 12:51 am
Location: Earth

Re: I have a checkmate in one hundred seventeen moves.

Post by Zach Wegner »

sje wrote:You'd rather have your program output the latter instead of the former.
No.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Spelling test: the first 63 powers of two

Post by sje »

Code: Select all

1
one

2
two

4
four

8
eight

16
sixteen

32
thirty-two

64
sixty-four

128
one hundred twenty-eight

256
two hundred fifty-six

512
five hundred twelve

1024
one thousand twenty-four

2048
two thousand forty-eight

4096
four thousand ninety-six

8192
eight thousand one hundred ninety-two

16384
sixteen thousand three hundred eighty-four

32768
thirty-two thousand seven hundred sixty-eight

65536
sixty-five thousand five hundred thirty-six

131072
one hundred thirty-one thousand seventy-two

262144
two hundred sixty-two thousand one hundred forty-four

524288
five hundred twenty-four thousand two hundred eighty-eight

1048576
one million forty-eight thousand five hundred seventy-six

2097152
two million ninety-seven thousand one hundred fifty-two

4194304
four million one hundred ninety-four thousand three hundred four

8388608
eight million three hundred eighty-eight thousand six hundred eight

16777216
sixteen million seven hundred seventy-seven thousand two hundred sixteen

33554432
thirty-three million five hundred fifty-four thousand four hundred thirty-two

67108864
sixty-seven million one hundred eight thousand eight hundred sixty-four

134217728
one hundred thirty-four million two hundred seventeen thousand seven hundred twenty-eight

268435456
two hundred sixty-eight million four hundred thirty-five thousand four hundred fifty-six

536870912
five hundred thirty-six million eight hundred seventy thousand nine hundred twelve

1073741824
one billion seventy-three million seven hundred forty-one thousand eight hundred twenty-four

2147483648
two billion one hundred forty-seven million four hundred eighty-three thousand six hundred forty-eight

4294967296
four billion two hundred ninety-four million nine hundred sixty-seven thousand two hundred ninety-six

8589934592
eight billion five hundred eighty-nine million nine hundred thirty-four thousand five hundred ninety-two

17179869184
seventeen billion one hundred seventy-nine million eight hundred sixty-nine thousand one hundred eighty-four

34359738368
thirty-four billion three hundred fifty-nine million seven hundred thirty-eight thousand three hundred sixty-eight

68719476736
sixty-eight billion seven hundred nineteen million four hundred seventy-six thousand seven hundred thirty-six

137438953472
one hundred thirty-seven billion four hundred thirty-eight million nine hundred fifty-three thousand four hundred seventy-two

274877906944
two hundred seventy-four billion eight hundred seventy-seven million nine hundred six thousand nine hundred forty-four

549755813888
five hundred forty-nine billion seven hundred fifty-five million eight hundred thirteen thousand eight hundred eighty-eight

1099511627776
one trillion ninety-nine billion five hundred eleven million six hundred twenty-seven thousand seven hundred seventy-six

2199023255552
two trillion one hundred ninety-nine billion twenty-three million two hundred fifty-five thousand five hundred fifty-two

4398046511104
four trillion three hundred ninety-eight billion forty-six million five hundred eleven thousand one hundred four

8796093022208
eight trillion seven hundred ninety-six billion ninety-three million twenty-two thousand two hundred eight

17592186044416
seventeen trillion five hundred ninety-two billion one hundred eighty-six million forty-four thousand four hundred sixteen

35184372088832
thirty-five trillion one hundred eighty-four billion three hundred seventy-two million eighty-eight thousand eight hundred thirty-two

70368744177664
seventy trillion three hundred sixty-eight billion seven hundred forty-four million one hundred seventy-seven thousand six hundred sixty-four

140737488355328
one hundred forty trillion seven hundred thirty-seven billion four hundred eighty-eight million three hundred fifty-five thousand three hundred twenty-eight

281474976710656
two hundred eighty-one trillion four hundred seventy-four billion nine hundred seventy-six million seven hundred ten thousand six hundred fifty-six

562949953421312
five hundred sixty-two trillion nine hundred forty-nine billion nine hundred fifty-three million four hundred twenty-one thousand three hundred twelve

1125899906842624
one quadrillion one hundred twenty-five trillion eight hundred ninety-nine billion nine hundred six million eight hundred forty-two thousand six hundred twenty-four

2251799813685248
two quadrillion two hundred fifty-one trillion seven hundred ninety-nine billion eight hundred thirteen million six hundred eighty-five thousand two hundred forty-eight

4503599627370496
four quadrillion five hundred three trillion five hundred ninety-nine billion six hundred twenty-seven million three hundred seventy thousand four hundred ninety-six

9007199254740992
nine quadrillion seven trillion one hundred ninety-nine billion two hundred fifty-four million seven hundred forty thousand nine hundred ninety-two

18014398509481984
eighteen quadrillion fourteen trillion three hundred ninety-eight billion five hundred nine million four hundred eighty-one thousand nine hundred eighty-four

36028797018963968
thirty-six quadrillion twenty-eight trillion seven hundred ninety-seven billion eighteen million nine hundred sixty-three thousand nine hundred sixty-eight

72057594037927936
seventy-two quadrillion fifty-seven trillion five hundred ninety-four billion thirty-seven million nine hundred twenty-seven thousand nine hundred thirty-six

144115188075855872
one hundred forty-four quadrillion one hundred fifteen trillion one hundred eighty-eight billion seventy-five million eight hundred fifty-five thousand eight hundred seventy-two

288230376151711744
two hundred eighty-eight quadrillion two hundred thirty trillion three hundred seventy-six billion one hundred fifty-one million seven hundred eleven thousand seven hundred forty-four

576460752303423488
five hundred seventy-six quadrillion four hundred sixty trillion seven hundred fifty-two billion three hundred three million four hundred twenty-three thousand four hundred eighty-eight

1152921504606846976
one quintillion one hundred fifty-two quadrillion nine hundred twenty-one trillion five hundred four billion six hundred six million eight hundred forty-six thousand nine hundred seventy-six

2305843009213693952
two quintillion three hundred five quadrillion eight hundred forty-three trillion nine billion two hundred thirteen million six hundred ninety-three thousand nine hundred fifty-two

4611686018427387904
four quintillion six hundred eleven quadrillion six hundred eighty-six trillion eighteen billion four hundred twenty-seven million three hundred eighty-seven thousand nine hundred four
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: I have a checkmate in one hundred seventeen moves.

Post by bob »

I disagree. I find "mate in 117 moves" much easier to parse/understand than "mate in one hundred and seventeen moves".
rjgibert
Posts: 317
Joined: Mon Jun 26, 2006 9:44 am

Re: I have a checkmate in one hundred seventeen moves.

Post by rjgibert »

Of course. The issue is not even a close. Writing it out is something one only does when forced to do it as in a bank draft. The only other exception I can think of is someone with some weird type of brain damage. Otherwise, I consider the effort entirely wasted.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: I have a checkmate in one hundred seventeen moves.

Post by sje »

Three more usages:

1) Annotation prose generation. In English at least, there are some places where digit strings do not belong (e.g., at the beginning of a sentence).

2) Voice synthesis output. Do you want to hear "Mate in twelve moves" or "Mate in one two moves"?

3) Ordinal adjectives. A slight modification of the SpellCardinal routines can produce the SpellOrdinal routines. With these, terms like "first", "second", and "forty-ninth" can be generated as well.
rjgibert
Posts: 317
Joined: Mon Jun 26, 2006 9:44 am

Re: I have a checkmate in one hundred seventeen moves.

Post by rjgibert »

sje wrote:Three more usages:

1) Annotation prose generation. In English at least, there are some places where digit strings do not belong (e.g., at the beginning of a sentence).

2) Voice synthesis output. Do you want to hear "Mate in twelve moves" or "Mate in one two moves"?

3) Ordinal adjectives. A slight modification of the SpellCardinal routines can produce the SpellOrdinal routines. With these, terms like "first", "second", and "forty-ninth" can be generated as well.
In (1) above, except for the 1st 100 numbers, I prefer to break this rule. BTW, I couldn't help, but chuckle, because you did not list your 3 examples with:

one)...
two)...
three)...

(2) is a good one I should have thought of, but managed not to.

(3) I prefer 1st, 2nd, 3rd,..., etc.
bnemias
Posts: 373
Joined: Thu Aug 14, 2008 3:21 am
Location: Albuquerque, NM

Re: I have a checkmate in one hundred seventeen moves.

Post by bnemias »

sje wrote:2) Voice synthesis output. Do you want to hear "Mate in twelve moves" or "Mate in one two moves"?
Don't 3rd party speech generators already implement this to avoid this exact problem? If I'm feeding a string to such a program to generate speech, I expect it to convert 12 to twelve for me, or at least consult the user's preferences before deciding how to output the sound.
Harald
Posts: 318
Joined: Thu Mar 09, 2006 1:07 am

Re: I have a checkmate in one hundred seventeen moves.

Post by Harald »

sje wrote:Consider:

"I have a checkmate in 117 moves."

vs

"I have a checkmate in one hundred seventeen moves."

You'd rather have your program output the latter instead of the former. And if you are coding in C++, I've got something that will help.
No.

"Ich setze schachmatt in einhundertsiebzehn Zügen." (german)
or
"Ich setze schachmatt in ein-hundert-siebzehn Zügen." (also german)

And consider this

123456789123456 is
123 trillion 456 billion 789 million 123 thousand 456 (english)
123 billionen 456 milliarden 789 millionen 123 tausend 456 (german)

But that is also nonsense. Perhaps this:

char *format_string_for_language[] = {
"I have a checkmate in %d moves.",
"Ich setze in %d Zügen schachmatt",
}
printf( format_string_for_language[lang], value );

And even this won't always work. You have to use completely different
algorithms for every language and every output string.

Harald
Daniel Shawul
Posts: 4186
Joined: Tue Mar 14, 2006 11:34 am
Location: Ethiopia

Re: I have a checkmate in one hundred seventeen moves.

Post by Daniel Shawul »

And even this won't always work. You have to use completely different
algorithms for every language and every output string.
why would one need different algorithms for this? Strings are placed in a resource file (like is done for windows APIs) and one could modify the strings to the required language. I would say different algorithm may be required for speaking 1500 either as 'one thousand five hundred' or just 'fifteen hundred'.

Daniel