Олимпиада для котов


#21

Вроде работает. Кто-нибудь из гуру гляньте пжл. Может можно оптимизировать?

Сводка

var getYears = function (yearBegin, yearEnd, sum) {
var array = [];
for (i=yearBegin; i<=yearEnd; i++) { //Перебираем годы
var year = String(i); //Переводим год из числа в строку
var sumOfDigits = 0; //Задаём переменную, где будем складывать цифры из года
for (j=0; j<=year.length-1; j++) { //Перепираем каждую цифру в году
sumOfDigits+=parseInt(year[j], 10);//Суммируем цифры в году
}
if (sumOfDigits == sum) {//Сравниваем сумму цифр в году с sum
array.push(i);//Если они равны, то добавляем этот год в массив
}
}
return array;
}


#22

смотря что под оптимизацией имеется ввиду.
из того что преподают в курсах уже нормально.


#24

Товарищи, помогите, пожалуйста, разобраться.

В первом сообщении Roman1 привел свое решение:

var getYears = function (year, yearEnd, sumYear) {
  var olymp = [];
  for (i = year; i <= yearEnd; i++) {
    var yearStr = String(i);
    var sumYe = Number(yearStr[0]) + Number(yearStr[1]) + Number(yearStr[2]) + Number(yearStr[3]);
    if (sumYe === sumYear) {
      olymp.push(i);
    }
  }
  return olymp;
}

Объясните, пожалуйста, зачем нужны вот эти участки кода и как они работают:

var yearStr = String(i);
var sumYe = Number(yearStr[0]) + Number(yearStr[1]) + Number(yearStr[2]) + Number(yearStr[3]);

Буду признателен, если кто-нибудь растолкует подробно.


#25

Пусть будет число 1234
var yearStr = String(i); // "1234" строка

Преобразование типа данных к строке
А строку уже можно рассматривать как массив (ну вот работает так строка как неразбитый массив, имеет некоторые схожие методы), взяв от нее N - элемент
Мы живем в третьем тысячелетии, поэтому нас интересуют четырехзначные цифры-строки (Император Человечества негодуэ, т.к. эту прогу не использовать в 40к году).

yearStr[0] + yearStr[1] + yearStr[2] + yearStr[3] // "1" + "2" + "3" + "4"

И теперь берем 0, 1, 2, 3 элемент числа-строки и складываем. А чтобы не произошла конкатенация строк, приведем взятые числа-строки к числам

Number( элемент_числа-строки ) // 1 + 2 + 3 + 4


#27

Hierumo, спасибо за ответ.
Логику преобразования (из строк в числа) понял.

Только я не понял зачем было вообще приводить данные — начальный и конечный годы к строке. Они же изначально приходят нам в виде чисел, — зачем нужна операция приведения числа к строке на первом шаге? Без нее никак никак не получится решить задачу?


#28

мы не можем из числа взять цифру на определенной позиции. это можно сделать либо из строки, либо массива. ну либо в цикле надо брать остаток от 10, потом делить на 10, округлять вниз до целого, и по-новой и все в цикле и еще временные переменные добавлять, морока кароч.


#29

ясно, спасибо за разъяснение!


#30

Пришел к такому решению.

var getYears = function (startYear, endYear, digit) {

var period = [startYear]; // создаем массив, сразу помещаем в него начальный год
for (i = 0; period[period.length - 1] < endYear; i++) { // наполняем массив пока не достигнем значения аргумента endYear
  period.push(period[i] + 1);
}

var currentYear; // создаем отдельную переменную для работы с каждым из элементов
var resultYears = []; // создаем массив, в который сохранятся подходящие значения

for (n = 0; n <= period.length - 1; n++) { // перебираем развернутый массив period
  currentYear = String(period[n]); // каждый элемент переводим в строку
  var sum = 0; // назначаем переменную для подсчета суммы в элементе
  for (j = 0; j <= currentYear.length - 1; j++) { // перебираем строку как массив
    sum += Number(currentYear[j]); // каждый символ приводим к числу и складываем
    }
  if (sum === digit) { // проверяем, совпадает ли сумма с аргументом digit
    resultYears.push(period[n]); // если да - отправляем в итоговый массив
    }
}
return resultYears; // возвращаем массив найденных годов как результат функции getYears
}

#31

Решение без перевода числа в строку и обратно, только на циклах.
Использование перевода, мне кажется, утяжеляет код.
Ну и этот вариант универсален - мало ли где будет Кекс в 40к году )

var getYears = function(year1, year2, num) {
var newArray = [];
while(year1 <= year2) {
var sum = 0;
for (var i = year1; i > 0; i = parseInt(i/10)) {
var n = i % 10;
sum += n;
}
if (sum == num) {
newArray.push(year1);
}
year1++;
}
return newArray;
}


#32
var getYears = function(firstY, lastY, numb) {
var olimp = [];
for (var i = firstY; i <= lastY; i++) {
 var sum = 0;
 var yearStr = String(i);
 for (var j = 0; j < yearStr.length; j++) {
  sum += Number(yearStr[j]); 
  }
  if(sum === numb) {
     olimp.push(i);
  }
}
 return olimp;
}

Такое вот решение получилось.


#33
const getYears = function (firstYear, lastYear, sumNumbers) {
  const goodYears = [];

  [...Array(lastYear + 1 - firstYear).keys()].forEach(item => {
    const currYear = item + firstYear;
    const arrYear = (currYear).toString().split('');
    const sumYear = arrYear.reduce((acc, curr) => +acc + +curr);

    if (sumYear === sumNumbers) goodYears.push(currYear);
  });

  return goodYears;
};

#34

var getYears = function (startYear, endYear, sumYear) {
var masYear = []
for (var i = startYear; i <= endYear; i ++) {
var sum = i % 10 + Math.floor(i / 10) % 10 + Math.floor(i / 100) % 10 + Math.floor(i / 1000);

if (sum === sumYear) {
  masYear.push(i);
}

}
return masYear;
}


#35
Как обычно через reduce
const getYears = (yearToStart, yearToEnd, neededSum) => {
  let initialArr = []
  
  for (let i = yearToStart; i <= yearToEnd; i++) {
    const sumInYear = String(i).split('').reduce((acc, item) => acc + Number(item), 0);
    (sumInYear === neededSum) ? initialArr.push(i) : initialArr;
  }
  
  return initialArr;
};

#36

нормально, но слишком много плюсов…+ много доп переменных - усложняет все это читаемость кода


#37

До чего смог додуматься. :disappointed_relieved:

var getYears = function (firstYear, lastYear, sum) {
    var massive = [],
        newMassive = [];
  for (var i = firstYear; i <= lastYear; i++) {
    massive.push(String(i));
  }
  for (var j = 0; j < massive.length; j++) {
      var answer = 0,
          result = massive[j];
      for (var z = 0; z < result.length; z++) {
        for (var x = 1; x <= 9; x++) {
          if (result[z] == x) {
            answer += x;
            var smell = massive[j];
          }
        }
      }
      if (answer == sum) {
        newMassive.push(+smell);
      }
  }
  return newMassive;
}

#38

Видел похожее, но мне мое больше нравится

var getYears = function (startYears, endYears, hasNumber) {
  var needYears = [];
  
  for (var i = startYears, o = 0; i <= endYears; i++, o = 0) {
    
    i = String(i);    
    
    for (var j = 0; j < i.length; j++) { o += Number(i[j]) }
    
    i = Number(i);
    
    if (o === hasNumber) { needYears.push(i) }
  }
  return needYears;
}

#39
const getYears = (startYear, endYear, sum) => {
  const result = [];
  for (let i = startYear; i <= endYear; i++) {
    String(i).split('').map(item => +item).reduce((item, acc) => item + acc) === sum && result.push(i);
  }
  return result;
};

#40

гениально!
подскажите почему result.push(i) всегда true отдает? а то чувствую чет от меня уходит. типа объект (ну т.к. метод это функция, а это объект) при логическом преобразовании всегда true, поэтому, да?


#41

Push возвращает новую длину массива, а это всегда положительное число и == true.


#42

Вот что вышло:

var getYears = function(yearStart, yearEnd, number) {    
  var years = [];
  for (var i = yearStart; i <= yearEnd; i++) { 
    var sum = 0;
    var yearString = String(i);
    for (var j = 0; j < yearString.length; j++) {
      var yearNumber = Number(yearString[j]);
      sum += yearNumber;
      }
    if (sum == number) {
      years.push(i);
      }
    }
  return years;
  }