Задачка про буквы, слоги и слова

Mausoleum

Восстановите все буквы в предложении
«Это предложение содержит ___ слов(? ___ ___ слог(?) и ____ ____ букв(?)»
Вопросительные знаки в скобках означают одно из возможных окончаний.

elena144

Это предложение содержит ___ слов(? ___ ___ слог(?) и ____ ____ букв(?)
Это предложение содержит двенадцать слов, двадцать шесть слогов и шестьдесят две буквы.
В чём проблема?

Mausoleum

Это предложение содержит двенадцать слов, двадцать шесть слогов и шестьдесят две буквы.
В чём проблема?
Ну, например, в том, что в твоем предложении 74 буквы. Предложение, конечно, должно верно себя описывать.

radion93

 
Предложение, конечно, должно верно себя описывать.

Это предложение содержит двенадцать слов, двадцать шесть слогов и семьдесят три буквы.
з.ы. по исходному запросу в гугле по второй ссылке виден ответ, даже не заходя никуда дальше.

Serg1912

Почему не считается знак препинания?

Mausoleum

Как много способов решить задачу, не решая задачу!..

radion93

 
Как много способов решить задачу, не решая задачу!..

Я ее решил, а потом посмотрел гугл.
Кто решил, что я посмотрел гугл и списал - неправы.
Почему не считается знак препинания?

Знак препинания - это слово, слог или буква?

iri3955

Просто задача разряда "Найти простые числа-близнецы, меньшие 1000", решается только перебором.
Единственное, что можно сделать - это сократить перебор. Слов - 12, слогов не меньше, чем 16 + 3 (сорок два) * 2 и не больше, чем 16 + 7 (восемьдесят четыре) * 2 + 2 слогов (а значит там "двадцать" или "тридцать", а значит "двадцать", так как первая семёрка из оценки становится 5
не меньше, чем 65 + 3 + 5 + 3 = 76 и не больше, чем 65 + 6 + 11 + 6 + 4 = 92 буквы,
Итого, у нас "Это предложение содержит двенадцать слов, двадцать слог и букв"
значит у нас либо семьдесят+ (тогда кол-во букв 80+ - не подходит либо восемьдесят+ букв, либо девяносто+ тодга из не больше 90, тоже не подходит). То есть
"Это предложение содержит двенадцать слов, двадцать слог и восемьдесят букв" - 76(+2*3)+ букв, 23(+2)+ слога.
"Это предложение содержит двенадцать слов, двадцать слог(a,ов) и восемьдесят букв" 83+ букв, 26+ слогов.
"Это предложение содержит двенадцать слов, двадцать слогов и восемьдесят букв" 84+ букв, 26+ слогов. Значит пропущенные слова, не две и не три.
"Это предложение содержит двенадцать слов, двадцать слогов и восемьдесят букв" 86+ букв, 26+ слогов. Теперь уже можно перебрать.
Это предложение содержит двенадцать слов, двадцать семь слогов и восемьдесят восемь букв.
Буквы - все символы. Если только буквы (а-я то тоже считатется.

iri3955

ИЧСХ, также подходит " Это предложение содержит двенадцать слов, двадцать шесть слогов и восемьдесят семь букв"

Mausoleum

ИЧСХ, также подходит " Это предложение содержит двенадцать слов, двадцать шесть слогов и восемьдесят семь букв"
:facepalm:
Понятию "буква" тебя в школе не научили, думаешь, length буквы считает?
Там 75 букв.

Vlad128

Не,

using System;
using System.Linq;

namespace Numbers {
class Program {
static void Main(string[] args)
{
string[] words = { "слово", "слова", "слов" };
string[] syllables = { "слог", "слога", "слогов" };
string[] letters = { "буква", "буквы", "букв" };
for( uint nwords = 1; nwords < 30; ++nwords ) {
for( uint nsyllables = 1; nsyllables < 100; ++nsyllables ) {
for( uint nletters = 1; nletters < 140; ++nletters ) {
string sentence = "это предложение содержит " +
ConvertToString( nwords, 0, words, 0 ) + " " +
ConvertToString( nsyllables, 0, syllables, 1 ) +
" и " + ConvertToString( nletters, 0, letters, 2 );

/*Console.WriteLine( sentence );
Console.WriteLine( CountWords( sentence ) );
Console.WriteLine( CountSyllables( sentence ) );
Console.WriteLine( CountLetters( sentence ) );
*/
if( CountWords( sentence ) == nwords &&
CountSyllables( sentence ) == nsyllables &&
CountLetters( sentence ) == nletters ) {
Console.WriteLine( sentence );
}
}
}
}
}

static uint CountWords(string x)
{
uint words = 0;
char prev = ' ';
foreach( char c in x ) {
if( prev == ' ' && c != ' ' ) {
++words;
}

prev = c;
}

return words;
}

static uint CountSyllables(string x)
{
uint syllables = 0;
foreach( char c in x ) {
if( "аяоёэеуюыи".Contains( c ) ) {
syllables++;
}
}

return syllables;
}

static uint CountLetters(string x)
{
uint letters = 0;
foreach( char c in x ) {
if( c != ' ' ) {
++letters;
}
}

return letters;
}

static int Declension(int x)
{
if( x / 10 != 1 ) {
if( x % 10 == 1 ) {
return 0;
} else if( 1 <= x % 10 && x % 10 <= 4 ) {
return 1;
}
}

return 2;
}

static string ConvertToString(ulong x, int exp, string[] parrots, int exc_index)
{
string[] digits = {
"",
"один ",
"два ",
"три ",
"четыре ",
"пять ",
"шесть ",
"семь ",
"восемь ",
"девять ",
"десять ",
"одиннадцать ",
"двенадцать ",
"тринадцать ",
"четырнадцать ",
"пятнадцать ",
"шестнадцать ",
"семнадцать ",
"восемнадцать ",
"девятнадцать "};

string[,] digits_exceptions = {
{ "", "одно ", "два " }, // слово
{ "", "один ", "два " }, // слог
{ "", "одну ", "две " } // буквы, тысячи
};

string[] tens = {
"",
"",
"двадцать ",
"тридцать ",
"сорок ",
"пятьдесят ",
"шестьдесят ",
"семьдесят ",
"восемьдесят ",
"девяносто "
};

string[] hundreds = {
"",
"сто ",
"двести ",
"триста ",
"четыреста ",
"пятьсот ",
"шестьсот ",
"семьсот ",
"восемьсот ",
"девятьсот "
};

string[,] others = {
{"ворона", "вороны", "ворон" },
{"тысяча ", "тысячи ", "тысяч "},
{"миллион ", "миллиона ", "миллионов "},
{"миллиард ", "миллиарда ", "миллиардов "},
{"триллион ", "триллиона ", "триллионов "},
{"триллиард ", "триллиарда ", "триллиардов "}
};

for( int i = 0; i < 3; i++ ) {
others[0, i] = parrots[i];
}

if( x == 0 ) {
if( exp == 0 ) {
return "ни одной " + others[0, 1];
} else {
return "";
}
}

int remainder = (intx % 1000);

string higher = ConvertToString( x / 1000, exp + 1, parrots, exc_index );

if( remainder == 0 && exp != 0 ) {
return higher;
}

string result = hundreds[remainder / 100];
result += tens[remainder % 100 / 10];
if( (exp == 0 || exp == 1) && remainder % 10 < 3 && remainder / 10 % 10 != 1 ) {
if( exp == 1 ) {
result += digits_exceptions[exc_index, remainder % 10 + (remainder / 10 % 10 == 1 ? 10 : 0)];
} else {
result += digits_exceptions[2, remainder % 10 + (remainder / 10 % 10 == 1 ? 10 : 0)];
}
} else {
result += digits[remainder % 10 + (remainder / 10 % 10 == 1 ? 10 : 0)];
}
result += others[exp, Declension( remainder % 100 )];

return higher + result;
}
}
}

Прога не для этого случая писалась, так что допилил на коленке, осталось немного говнокода, сильно не пинайте. Выдает один из ответов в треде :grin:

iri3955

Я тебе русским по белому написал, что считал из предположения, буква = символ.
Так было мне проще. Посчитай уже сам с буквами.

luherstag

Кстати, перебор для этой задачи не обязателен, можно так:
        static void Main(string[] args)
{
var s = "";
while (true)
{
var s2 = Describe(s);
if (s == s2)
{
Console.WriteLine(s);
break;
}
s = s2;
}
}

static string Describe(string sentence)
{
return "это предложение содержит " +
ConvertToString(CountWords(sentence 0, words, 0) + " " +
ConvertToString(CountSyllables(sentence 0, syllables, 1) +
" и " + ConvertToString(CountLetters(sentence 0, letters, 2);
}

static string[] words = { "слово", "слова", "слов" };
static string[] syllables = { "слог", "слога", "слогов" };
static string[] letters = { "буква", "буквы", "букв" };

Разумеется, завершаемость не гарантируется, это зависит от начальных условий. Но на практике весьма вероятна!
Работает и в более сложных случаях, например, так можно построить предложение, описывающее частоты всех символов в нём.

luherstag

В этом предложении тридцать одна буква "а", двадцать восемь букв "б", сорок шесть букв "в", тридцать пять букв "д", двадцать одна буква "е", две буквы "ж", десять букв "и", одна буква "й", двадцать девять букв "к", две буквы "л", шесть букв "м", одиннадцать букв "н", тринадцать букв "о", три буквы "п", девять букв "р", девять букв "с", двадцать семь букв "т", двадцать восемь букв "у", одна буква "ф", двенадцать букв "ц", две буквы "ч", три буквы "ш", одна буква "щ", девять букв "ы", двадцать четыре буквы "ь", две буквы "э" и семь букв "я".
Оставить комментарий
Имя или ник:
Комментарий: