Advent of Code 2019

Odpowiedz Nowy wątek
2019-12-02 10:37
0

Bawi się ktoś w Advent of Code? --> https://adventofcode.com/
Jako, że dopiero uczę się programowania i jestem leszczem, to wyłożyłem się już na drugim zadaniu dnia pierwszego. Ale od początku.
W pierwszym zadaniu chodzi o to by policzyć ilość paliwa dla modułów statku kosmicznego. Każdy moduł ma masę, na podstawie której liczy się ilość paliwa:
masa paliwa = masa modułu / 3 (zaokąglona w dół ) - 2.
Masy modułów (jest ich kilkadziesiąt) podane są jako wartości całkowitoliczbowe w jednej kolumnie.
Skopiowałem je więc do pliku txt. Użyełm klasy RandomAccessFile i w pętli while zczytałem, policzyłem i zsumowałem ilość paliwa dla całego statku. Poszło gładko, wynik się zgadzał.

W części drugiej zadania należało uwzględnić także masę paliwa, czyli masę paliwa obliczonego za pierwszym razem, potem paliwo dla paliwa z drugiego obliczenia itd. aż wartość wyjdzie rózwna zero lub ujemna. Ilość paliwa dla paliwa obliczamy tak samo jak wcześniej: masa paliwa = masa paliwa bieżącego / 3(zaokąglona w dół ) - 2.
tu już poszło gorzej. Zagnieździałem kolejną pętlę while i kombinowalem na różne sposoby. Niestety wynik nie jest prawidłowy.
Ktoś to rozwiązał lub ma pomysł?
Poniżej mój upośledzony kod:

import java.io.*;
public class Fuel {
    public static void main(String[] args) {
        if(args.length<1){
            System.out.println("Wywołanie programu");
            return;
        }

        File file = new File(args[0]);

        if(!file.exists()){
            System.out.println("Plik nie istnieje");
            return;
        }
        RandomAccessFile raf = null;
        try{
            raf = new RandomAccessFile(file, "r");
        }catch (FileNotFoundException e){
            System.out.println("Nie znalezono pliku" + e);
        }
        String line = " ";
        int moduleMass = 0;
        double fuelSum = 0.0;

        double finalFuelMass = 0;
        double tempFuelMass;

        try{
            while((line = raf.readLine()) != null){
                moduleMass = Integer.parseInt(line);
                double initFuelMass = moduleMass/3 - 2;
                tempFuelMass = initFuelMass;
                while (tempFuelMass > 0){
                    tempFuelMass = tempFuelMass/3 - 2;
                    finalFuelMass = finalFuelMass + tempFuelMass;
                }
                fuelSum = fuelSum + initFuelMass +finalFuelMass;
            }
            raf.close();
        }catch (IOException e){
            System.out.println("Błąd wejścia/wyjścia");
        }
        System.out.println("Paliwo dla modułów: " + (int)fuelSum);
    }

}
dla tempFuelMass == 5, tempFuelMass > 0, ale w środku tego obrotu pętli dodajesz do sumy -1. - enedil 2019-12-02 11:16
Faktycznie, zaraz coś pokombinuję z tym warunkiem. Dzięki za podpowiedź. - pulaas 2019-12-02 11:51

Pozostało 580 znaków

2019-12-02 11:50
0

Jakie wyniki Ci wychodza dla danych testowych? Nie wnikając w kod, nie powinno być czasem: while (tempFuelMass > 6){? Wtedy ujemne paliwo nie wejdzie do sumy.


edytowany 1x, ostatnio: lion137, 2019-12-02 11:50

Pozostało 580 znaków

2019-12-02 11:58
0
                while (tempFuelMass > 0){
                    tempFuelMass = tempFuelMass/3 - 2;
                    finalFuelMass = finalFuelMass + tempFuelMass;
                }

Tu masz błąd. Zauważ ze policzyłes nowe tempFuelMass które może być ujemne(!) i tego nie sprawdziłeś, stąd też możesz od final mass coś przypadkiem odjąć.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

2019-12-02 12:14
0

Faktycznie powinno byc (tempFuelMass > 6).
Mam jeszcze jakiś problem z sumowaniem wartości.
W drugiej wersji kodu(nie wklejałem go tu), gdzie liczenie paliwa dla modułów i liczenie paliwa dla paliwa rozbiłem na dwie metody, a później dodałem dwie wartości do siebie, zmiana warunku na tempFuelMass > 6 dała poprawny wynik i zadanie zostało zaliczone.
Niestety w kodzie, który wkleiłem powyżej coś mi źle liczy sumę całkowitą paliwa.

Pozostało 580 znaków

2019-12-02 12:19
0

Poniżej kod w wersji z dwiema metodami. Policzył prawidłowo. (Wiem, że można było uniknąć powtarzalności kodu ale na szybko kodziłem).

import java.io.*;

public class Fuel {

    static double fuelForFuel(String[] args){
        if(args.length<1){
            System.out.println("Wywołanie programu");

        }

        File file = new File(args[0]);

        if(!file.exists()){
            System.out.println("Plik nie istnieje");

        }
        RandomAccessFile raf = null;
        try{
            raf = new RandomAccessFile(file, "r");
        }catch (FileNotFoundException e){
            System.out.println("Nie znalezono pliku" + e);

        }
        String line = " ";
        int moduleMass;
        double fuelSum = 0.0;
        double finalFuelMass = 0;
        double tempFuelMass;

        try{
            while((line = raf.readLine()) != null){
                moduleMass = Integer.parseInt(line);
                double initFuelMass = moduleMass/3 - 2;
                tempFuelMass = initFuelMass;
                while (tempFuelMass > 6){
                    tempFuelMass = (int)tempFuelMass/3 - 2;
                    finalFuelMass = finalFuelMass + tempFuelMass;
                }

                fuelSum =+ finalFuelMass;
            }
            raf.close();
        }catch (IOException e){
            System.out.println("Błąd wejścia/wyjścia");
        }

        return fuelSum;
    }
    static double fuelForModules(String[] args){
        if(args.length<1){
            System.out.println("Wywołanie programu");
        }

        File file = new File(args[0]);

        if(!file.exists()){
            System.out.println("Plik nie istnieje");
        }
        RandomAccessFile raf = null;
        try{
            raf = new RandomAccessFile(file, "r");
        }catch (FileNotFoundException e){
            System.out.println("Nie znalezono pliku" + e);
        }
        String line = " ";
        int moduleMass = 0;
        double sum = 0.0;

        try{
            while((line = raf.readLine()) != null){
                moduleMass = Integer.parseInt(line);
                double initFuelMass = moduleMass/3 - 2;
                sum = sum + initFuelMass;
            }
            raf.close();
        }catch (IOException e){
            System.out.println("Błąd wejścia/wyjścia");
        }

        return sum;
    }

    public static void main(String[] args) {
        System.out.println("Fuel for modules: " +fuelForModules(args));
        System.out.println("Fuel for fuel: " +fuelForFuel(args));

        System.out.println("Suma: " + (fuelForModules(args) + fuelForFuel(args)));

    }

}
Strasznie pogmatwany kod, rozbij sobie może na jakieś mniejsze metody. Ja to zrobiłem w 3 niewielkich metodkach: 1 - wczytanie liczb z pliku do listy, zwracana ofc lista; 2 - metoda, która dla DANEGO (pojedynczego) modułu liczy Ci sumę paliwa (walnij prostego while'a), zwracana liczba i 3 metoda, która streamem leci po liście, w funkcji mapującej referencja do poprzedniej metody, redukcja i gotowe ;p Staraj się tworzyć proste, niewielkie metody, będzie Ci o wiele łatwiej ;p - Skoq 2019-12-02 16:17
W wolnej chwili , dla ćwiczenia, uporządkuję to tak jak sugerujesz. Ostatnio za bardzo się rozpraszam od mojego toku nauki javy. Kończę przerabiać kurs Javy EE, do tego kolekcje obiektów z książki Eckela, w drodze zamówiona ksiązka do Javy 8 i do tego dłubię jakiś zadania znalezione w sieci. A czas nie jest z gumy... Trzeba się sprężyć bo chciałbym niedługo zacząć rozsyłać CV. - pulaas 2019-12-02 16:31

Pozostało 580 znaków

2019-12-02 23:41
0

Nie Macie w tej Javie, map, reduce, streamów, etc.:)? Wczytaj plik i Zmapuj full_fuel na wejście + reduce = suma. Tak to wygląda w Pythonie:

def full_fuel(num):
    a_sum = 0
    while True:
        if num < 6:
            return a_sum
        t = num // 3 - 2 # // - dzielenie w integerach
        a_sum += t
        num = t

def solution(f_name):
    with open(f_name) as f:
        s = sum(full_fuel(int(line)) for line in f) # list comprehension, to samo co map full_fuel na f
        return s

A robie rekurencje ogonową ukradli w tym full_fuel jak już się tak chcesz czepiać? :P - Shalom 2019-12-02 23:42
Dokladnie tak, ukradli mi TCO w Pythonie:), ale przecież TCO to nic innego jak pętla while:) - lion137 2019-12-02 23:45
Ale jak bardziej funkcyjnie by wyglądało! :P - Shalom 2019-12-03 00:11
Wyglądało by funkcyjnie, fakt, dostałbym +10 do bycia "cool kid":) a ja tu stare, toporne, while:) - lion137 2019-12-03 00:13
To zadanko to akurat i bez TCO pójdzie - Maciej Cąderek 2019-12-03 01:24
Ale będzie mało eleganckie... :P - Shalom 2019-12-03 01:31

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0