Loading...
peter_arsov avatar peter_arsov 1 Точки

Condense Array to Number - Tech Fundamentals with Java and PHP

Condense Array to Number
Write a program to read an array of integers and condense them by summing adjacent couples of elements until a
single integer is obtained. For example, if we have 3 elements {2, 10, 3}, we sum the first two and the second two
elements and obtain {2+10, 10+3} = {12, 13}, then we sum again all adjacent elements and obtain {12+13} = {25}.
Examples:

---------------------
Input: 2 10 3

Output: 25

Comments:2 10 3 -> 2+10 10+3 -> 12 13 -> 12 + 13 -> 25

---------------------

Input: 5 0 4 1 2

Output: 35

Comments: 5 0 4 1 2 -> 5+0 0+4 4+1 1+2 ->5 4 5 3 ->5+4 4+5 5+3 ->9 9 8 ->9+9 9+8 ->18 17 ->18+17 ->35

---------------------

Input: 1

Output: 1

Comments:  1 is already condensed to number

------------------------------------------------------------------

Здравейте,

бих искал малко помощ как да си оправя алгоритъма в задачата да работи напълно, понеже първия и третия примерни тестове работят, а втория - не.

Линк с решението ми: https://pastebin.com/QRGvTaaC

 

0
Fundamentals Module 07/02/2019 16:12:39
peter_arsov:
Answer is given.
arjunah avatar arjunah 9 Точки

Здравей, видях няколко неща в кода ти:

1. Тази проверка, и съответно променливата elem, са ти ненужни:

if (intItems[0] == intItems[elem - 1]) {
    System.out.printf("%d is already condensed to number", intItems[0]);
    return;
} 

Първо, защото това, което е като comments в условието на задачата, не трябва да се печата на конзолата - при всички случаи трябва да се отпечата само едно число; второ, самата ти проверка е некоректна: ако имаш вход "2 2" тогава пак ще ти изкара "2 is already condensed to number"

2. Логиката ти за пресмятане на sum е неправилна в случая и не работи за масив с повече от три елемента, защото ти реално прaвиш следното:

sum = (intItems[0] + intItems[1]) + (intItems[1] + intItems[2]) + (intItems[2] + intItems[3]) + ... и т.н.

А всъщност ти трябва това:

sum = (((intItems[0] + intItems[1]) + (intItems[1] + intItems[2])) + ((intItems[1] + intItems[2]) + (intItems[2] + intItems[3]))) +
...и т.н., което е пример за масив с 4 елемента, като за повече става по-дълго и с повече скоби, но се надявам да си схванал логиката :-)

Т.е., след първото събиране трябва да запазваш получените нови елементи, за да ги събираш отново по двойки по същата логика, а не просто да получиш общия им сбор след първото събиране.

Ето моето примерно решение:

public class CondenseArrayToNumber{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] input = Arrays.stream(sc.nextLine().split(" ")).mapToInt(e -> Integer.parseInt(e)).toArray();
        while (input.length > 1) {
            int[] condensed = new int[input.length - 1];
            for (int i = 0; i < condensed.length; i++) {
                condensed[i] = input[i] + input[i + 1];
            }
            input = condensed;
        }
        System.out.println(input[0]);
    }
}

Надяваме се да съм ти бил полезен!

2
05/02/2019 10:51:28
peter_arsov avatar peter_arsov 1 Точки

Благодаря, за подробния отговор!

Не съм сигурен дали разбирам какво прави input = condensed;. 
При всяко приключване на for-цикъла, ако input == 5, а condensed == 4, и ги направим равни,
то нали тогава input ще намалява и while - цикълът ще върти, докато input > 1?

 

0
05/02/2019 11:33:53
arjunah avatar arjunah 9 Точки

Нужно ни е да намаляваме дължината на масива всеки път с 1, защото след всяка итерация елементите на новия масив намаляват с един.

input = condensed кара input[] да сочи към condensed[] в паметта и така input.length става с 1 по-малко всеки път, докато не стане = 2, при което condensed.length = 1 и цикълът прекъсва, понеже ни е нужно само едно число за изход. 

А condensed[input.length - 1], понеже при всяка итерация от събирания елементите на новия масив намаляват с един, докато не остане само един елемент, който да се отпечата на изхода. Затова и не ти е нужна проверка, ако входът е само от едно число.

0
iwanovw avatar iwanovw 7 Точки

Не знам този код как работи на Java , но на PHP не работи. По простата причина, че 

condensed.length = 1

и въртиш цикъла до 1, вместо до 2. Следователо се извършва събирането за първите две числа. Би трябвало да е:

i < input.length - 1 

 

0
05/02/2019 20:46:03
arjunah avatar arjunah 9 Точки

Здравей, реално condensed.length e равно на input.length - 1, понеже condensed.length се инициализира с дължина input.length - 1, така че не разбирам какъв точно е проблемът? 

В първия цикъл може да се влезе само докато input.length >= 2 (цикълът се върти, докато не останат два елемента в масива input[]); влиза се в while цикъла, след което преди итерацията във for цикъла се инициализира масив condensed [] = input.length - 1 (т.е. condensed става с 1 елемент при последното завъртане на while цикъла) и в самия for цикъл на индекс [0] от масива condensed[] се присвоява стойността от input[i] + input[i + 1] (input[] все още е с два елемента), след което for цикълът прекъсва (понеже i става = 1, а ограничението е < condensed.length, което в случая е 1) и input[] се пренасочва към condensed[], т.е. вече input.length = 1, при което се прекъсва и while цикъла.

Кодът работи 100/100, би трябвало логиката да работи и на PHP, освен ако там няма някакви други ограничения за масивите, не съм запознат въобще с PHP. Според мен някъде бъркаш input[] с condensed[], или дължината на input[] с дължината на condensed[] (condensed.length винаги e с 1 по-малко от input.length).

0
iwanovw avatar iwanovw 7 Точки

Няма проблем, просто ми стана интересно как работи при вас правилно, защото на PHP го пробвах и показва грешни резултати. Когато зададеш масив с елемент condensed = [input. length - 1] като резултат какво ти връща? Аз дъмпнах и ми връща на [0] => 2 // дължината при вход (2, 10, 3). Следователно в цикъла i < condensed.lenght // 1 и става чудото защото върти до 1 и спира. Иначе я реших по подобен начин с лека преработка като цикъла го въртя до input. length - 1

0
06/02/2019 18:09:40
arjunah avatar arjunah 9 Точки

Първо се извинявам на колегата по-горе, че му спамим поста с PHP :-)

Заинтригува ме какво точно не работи в PHP при теб и седнах да разгледам малко PHP синтаксис. Позволих си да "преведа" моя код от Java на PHP:

<?php
$stringInput = readline();
$input = explode(" ", $stringInput);
while (count($input) > 1) {
    $condensed = array_fill(0, count($input) - 1, 0);
    for ($i = 0; $i < count($condensed); $i++) {
        $condensed[$i] = $input[$i] + $input[$i + 1];
    }
    $input = $condensed;
}
echo $input[0];

Не ми се занимаваше да конфигурирам PHP дебъгер и да го тествам локално, но го тествах в Judge на инстанцията за Tech PHP и ми даде 100/100 от първия път. Отново - не виждам някъде да има проблем: логиката е една и съща, синтаксисът е различен. Според мен, това, което не работи при теб, е заради грешка в кода, който си написал, а не заради самия начин на решаване на задачата, използваната логика, още по-малко пък заради езика, на който е написан кода. Все пак, твоят коментар ме подтикна да се запозная малко и с PHP, за което ти благодаря. Научих и пробвах нещо ново днес :-)

0
iwanovw avatar iwanovw 7 Точки

Аха ето къде изпускам. Ти използваш array_fill() за да създадеш още един индекс и елементите на масива стававт два , не се бях сетил. Аз се ръководих от подсказките в лекцията и зададох $condensed = [count($input) - 1] и от там се шашка цикълът като задам $i < count($condensed); Така де и аз се извинявам за спама и ти благодаря за съвета. :)

0
06/02/2019 21:37:16
svetlakrasteva avatar svetlakrasteva 7 Точки

Благодаря, и на мене ми помогна.

0
amdimov avatar amdimov 0 Точки

Благодаря за решението и доброто обяснение. Блъсках си главата доста време, но това е защото не знаех, че може да се намали размера на масива с простото 

input = condensed;

 

0
iwanovw avatar iwanovw 7 Точки

Пробвах това решение за тест на PHP, но нещо извършва събирането само на индекси 0 и 1 /2, 10/, а 2-я го изрязва. Следвотелно връща 12 като резултат. 

0
05/02/2019 18:31:03
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.