Професионална програма
Loading...
peter_arsov avatar peter_arsov 0 Точки

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 0 Точки

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

Не съм сигурен дали разбирам какво прави 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