JavaRush/Java блог/Архив info.javarush/Кухня(); Задание N32.
terranum
28 уровень

Кухня(); Задание N32.

Статья из группы Архив info.javarush
участников
Кухня(); Задание N32. - 1 Правила [Одномерные массивы] 32. Секретный замок для сейфа состоит из 10 расположенных в ряд ячеек, в которые надо вставить игральные кубики. Но дверь открывается только в том случае, когда в любых трех соседних ячейках сумма точек на передних гранях кубиков равна 10. (Игральный кубик имеет на каждой грани от 1 до 6 точек.) Напишите программу, которая разгадывает код замка при условии, что два кубика уже вставлены в ячейки. --- --- --- --- --- --- --- Каким оружием могли бы быть разные языки программирования --- --- --- --- --- --- ---
Комментарии (59)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Docktor91
Уровень 40
14 сентября 2014, 14:17
еще раз скажу, у меня в коде нужно вставить правильно кубики, тогда решение будет нормально(правда если честно, у меня там косячок есть)))
[0, 0, 0, 0, 0, 0, 0, 5, 0, 6] например здесь возьмем три последние, очевидно что сумма уже не равна 10
значит вставлены не верно, можно добавить еще один цикл для проверки элементов меньше 1, и выкрикивать эксепшн
Docktor91
Уровень 40
14 сентября 2014, 15:13
что то типо того))
public static void getPassword(int...arr)
    {

        int[] res = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        int fi = 0;                                               //first index of included cube
        int si = 0;                                               //second index of included cube
        for (int i = 0; i < arr.length; i++)                      //get indexes
        {
            fi = arr[fi] > 0 ? fi : i;
            si = arr[fi] > 0 && arr[i] > 0 ? i : si;
        }
        int pos2 = (si - fi) % 3 > 1 ? 2 : 1;                         //position of second index in d arr
        int pos3 = (si - fi) % 3 > 1 ? 1 : 2;
        int[] d = new int[3];                                         //is a 3 el sequence for res arr
        d[fi % 3] = arr[fi];                                        //first ind pos
        d[(fi + pos2) % 3] = arr[si];                               //second ind pos
        d[(fi + pos3) % 3] = 10 - arr[fi] - d[(fi + pos2) % 3];     //third value
        for (int i = 0; i < res.length; i++)                        //fill res array
        {
            if (d[i % 3] < 1 || d[i % 3] > 6)                       //check valid
                throw new IllegalArgumentException("Password never passed");
            res[i] = d[i % 3];
        }
        if (res[fi] != arr[fi] || res[si] != arr[si])               //check valid
            throw new IllegalArgumentException("Password never passed");
        System.out.println(Arrays.toString(res));                   //sout
    }
Airon
Уровень 34
15 сентября 2014, 18:00
Ну это все класно и быстро, но вот как побороть страх при виде деления % на число больше 2-х? =)
Docktor91
Уровень 40
15 сентября 2014, 19:48
все просто результат будет 0, 1, 2 не больше не меньше
Airon
Уровень 34
14 сентября 2014, 13:38
Хорошая задача, сначала кинула в пот из-за на первый взгляд большущего кода. Потом решив немножко подглядеть решение посмотрел тут код, но оказалось невероятно сложно и абсолютно не понятно или мой скилл еще достаточно девственен. Хотя и поигрался с приведенными тут кодами, но некоторые массивы были:
[0, 0, 0, 0, 0, 0, 0, 5, 0, 6]
[6, 5, -1, 6, 5, -1, 6, 5, -1, 6]
и еще по такому типу
[0, 0, 0, 0, 6, 5, 0, 0, 0, 0]
[-1, 6, 5, -1, 6, 5, -1, 6, 5, -1]
что не есть решение.
Итак немного поднявшись и изменив угол обзора, увидел замыливание в задаче, оказалось, что для решение надо перенести координатную ось до первого кубика, и если эта правая часть решаема то по полученному образцу (паттерну) добрать левую часть массива.
Вот мой вариант, еще есть куда оптимизировать, но это повлечет кучу проверок и еще увеличение кода:
public class thekitchen {
    public static void main(String[] args) {
        Random random = new Random();
        int[] numbers = new int[10];
        while (true) {
            int i1 = random.nextInt(10);
            int i2 = random.nextInt(10);
            if (i1 != i2) {
                numbers[i1] = random.nextInt(6) + 1;
                numbers[i2] = random.nextInt(6) + 1;
                break;
            }
        }
        System.out.println(Arrays.toString(numbers));
        System.out.println(Arrays.toString(getPassword(numbers)));
    }

    public static boolean isOpen(int... array) {
        for (int i = 1; i < array.length - 1; i++)
            if (array[i - 1] + array[i] + array[i + 1] != 10)
                return false;
        return true;
    }

    public static int[] getPassword(int... array) {
        int index = 0;
        for (int i = 0; i < array.length; i++)
            if (array[i] != 0) {
                index = i;  // Находим индекс самого левого/первого кубика
                break;
            }
    
terranum
Уровень 28
4 сентября 2014, 12:59
Не буду вас больше кипятить, go дальше)

Слыхали ты в гугл устроился, ну как там?)))
terranum
Уровень 28
4 сентября 2014, 13:00
Уже поправился?)
Docktor91
Уровень 40
4 сентября 2014, 13:17
)))ахах
после 5 уровня отправил резюме в гугл, и теперь я ведущий спец там)))
terranum
Уровень 28
4 сентября 2014, 12:45
Ладно ребят, выдвигаю тезис, от него будем скакать.
«Клиент всегда прав.»
Соглашаемся и уточняем условие, не соглашаемся, значить скачим дальше.
Docktor91
Уровень 40
4 сентября 2014, 12:53
я не понял особо кто тут, за что, но задачка была бы интересней, если
«какие бы три ячейки не взяли сумма была бы 10»
Vash_the_Stampede
Уровень 11
4 сентября 2014, 13:18
это возможно?
Docktor91
Уровень 40
4 сентября 2014, 13:19
2,4,4,2,4,4,2,4,4,2,4
Vash_the_Stampede
Уровень 11
4 сентября 2014, 13:20
2 + 2 + 2 != 10
4 + 4 + 4 != 10
Docktor91
Уровень 40
4 сентября 2014, 13:21
ааа… три соседние… дружище ты чего
Vash_the_Stampede
Уровень 11
4 сентября 2014, 13:31
какие бы три ячейки не взяли сумма была бы 10)
Docktor91
Уровень 40
4 сентября 2014, 13:32
тут между строк читать надо)
Vash_the_Stampede
Уровень 11
4 сентября 2014, 14:40
я бы пошутил, что «между одной строк(не опечатка) читать непросто», но там их две
Docktor91
Уровень 40
4 сентября 2014, 16:28
а ты смекаешь))
Docktor91
Уровень 40
4 сентября 2014, 12:28
извините за нерефакторенность
terranum
Уровень 28
4 сентября 2014, 12:50
Что за магический куб поглощающий точки на других кубиках?
[5, 6, 0, 0, 0, 0, 0, 0, 0, 0]
[-1, 6, 5, -1, 6, 5, -1, 6, 5, -1]
Подозревается что во все непроходимо вставить.
[0, 4, 0, 0, 6, 0, 0, 0, 0, 0]
[0, 4, 6, 0, 4, 6, 0, 4, 6, 0]

Судя по решениям пора открывать школу хитрых хакеров)))
Docktor91
Уровень 40
4 сентября 2014, 12:52
подразумевается, что кубики вставлены верно,
вставь кубики верно, и все должно заработать
Docktor91
Уровень 40
4 сентября 2014, 12:28
public static void getPassword(int...arr)
	{
		
		int[] res=new int[]{0,0,0,0,0,0,0,0,0,0};
		int fi=0;
		int si=0;
		for (int i=0;i<arr.length;i++)
		{
			if (arr[i]>0)
			{
				if (fi==0)
					fi=i;
				else
					si=i;
			}
		}
		int[] d=new int[3];
		d[fi%3]=arr[fi];
		if (arr[fi]==arr[si])
			d[(fi+1)%3]=(10-arr[fi]-arr[si])/2;
		else
			d[(fi+1)%3]=arr[si];
		d[(fi+2)%3]=10-arr[fi]-d[(fi+1)%3];
		
		for (int i=0;i<res.length;i++)
		{
			res[i]=d[i%3];
		}
		System.out.println(Arrays.toString(res));
	}
Vash_the_Stampede
Уровень 11
3 сентября 2014, 22:23
Прошлый код опять оказался неверным, вроде этот рабочий (там же генератор входных данных и проверка):
public class MainClass {

    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 1000; i++) {
            int[] arr = generateInputForKitchen32();
            int[] copy = Arrays.copyOf(arr, arr.length);
            kitchen32(arr);
            for (int j = 0; j < arr.length - 2; j++) {
                if (arr[j] + arr[j + 1] + arr[j + 2] != 10) {
                    System.out.println("Wrong result");
                    System.out.println(Arrays.toString(copy));
                    System.out.println(Arrays.toString(arr));
                    System.out.println();
                    System.exit(0);
                }
            }
        }
    }

    public static int[] generateInputForKitchen32() {
        int k1, v1, k2, v2;

        k1 = (int) (Math.random() * 10);
        v1 = (int) (Math.random() * 6) + 1;

        do {
            k2 = (int) (Math.random() * 10);
        }
        while (k1 == k2);

        if (k1 % 3 == k2 % 3) {
            v1 = v2 = v1 > 5 ? v1 : (int) (Math.random() * 4) + 1;
        }
        else
            do {
                v2 = (int) (Math.random() * 6) + 1;
            }
            while (v1 + v2 < 4 || v1 + v2 > 9);

        int[] arr = new int[10];
        arr[k1] = v1;
        arr[k2] = v2;

        return arr;
    }

    public static int[] kitchen32(int[] arr) {
        final int N = arr.length; // number of cubes
        final int S = 10; // sum of three nearby cubes

        int k1 = 0;
        while (arr[k1] == 0) {
            k1++;
        }

        int k2 = k1 + 1;
        while (arr[k2] == 0) {
            k2++;
        }

        if (k1 % 3 == k2 % 3) {
            if (arr[k1] != arr[k2]) {
                System.out.println("Impossibile!"); // Italian
                return arr;
            }
            els
terranum
Уровень 28
3 сентября 2014, 20:10
Необходимо еще раз прочитать условие, в данной задаче нет невозможных решений!
Vash_the_Stampede
Уровень 11
3 сентября 2014, 20:20
имеешь ввиду, что кубики вставлены правильно? я не вижу, где в задании сказано, что он стоят как надо.
terranum
Уровень 28
3 сентября 2014, 21:30
У нас массив на 10 ячеек. Две случайные ячейки заполнены символами от 1 до 6, остальные нулями. Реализовать логику метода так, что бы ячейки с нулевыми значениями были заполнены значениями от 1 до 6, и что бы в любых трех подряд идущих ячейках сумма цифр равнялась 10.
Vash_the_Stampede
Уровень 11
3 сентября 2014, 21:42
если две ячейки заполнены числами, в сумма дающими больше 9?
arr = { 6, 0, 0, 0, 0, 0, 0, 5, 0, 0 }
тут уж без вариантов, хотя под условия катит
terranum
Уровень 28
3 сентября 2014, 23:50
[6, 0, 0, 0, 0, 0, 0, 5, 0, 0]
[6, 2, 2, 1, 1, 1, 1, 5, 1, 1]
Сумма первых трех равна 10.
Vash_the_Stampede
Уровень 11
4 сентября 2014, 00:52
По условию, как я понял, любая тройка соседних чисел должна давать в сумме 10, а не первых трех. На передних гранях — имеется ввиду сторона кубика, коих у него 6
terranum
Уровень 28
4 сентября 2014, 01:02
Любых трех, первых, последних, в середине, где угодно. В массиве должен быть как минимум один участок из 3-х подряд идущих элементов сумма которых 10.
terranum
Уровень 28
4 сентября 2014, 01:06
Не имеется ввиду, каждые три подряд идущие.
Vash_the_Stampede
Уровень 11
4 сентября 2014, 01:34
если бы любая тройка подошла бы, то написали бы " на каких-либо трех соседних" или типа того. давай «используем подсказку»помощь зала") я задам опрос
Docktor91
Уровень 40
4 сентября 2014, 11:34
когда в любых трех соседних ячейках
выделим главное
в любых трех соседних ячейках
т.е. какие бы не взяли три подряд идущие ячейки, сумма равна 10
Vash_the_Stampede
Уровень 11
4 сентября 2014, 12:13
я правильно понял, ты со мной согласился?
terranum
Уровень 28
4 сентября 2014, 12:14
[6, 6, 0, 0, 0, 0, 0, 0, 0, 0]
То есть замок уже не открыть? И таких еще куча ситуаций.
Vash_the_Stampede
Уровень 11
4 сентября 2014, 12:15
и-мен-но! )
terranum
Уровень 28
4 сентября 2014, 12:18
Почему тогда просто не написать так? Но дверь открывается только в том случае, когда в каждых трех соседних ячейках сумма точек на передних гранях кубиков равна 10.
Vash_the_Stampede
Уровень 11
4 сентября 2014, 12:20
в вузах говорят «для любого ...»
terranum
Уровень 28
4 сентября 2014, 12:22
Сколько в таком случае «троек» в массиве на 10?
Docktor91
Уровень 40
4 сентября 2014, 12:28
нет, наоборот
Vash_the_Stampede
Уровень 11
4 сентября 2014, 12:42
как, наоборот? я считал и считаю, что все тройки должны давать 10 в сумме по условию, ты разве не согласен?
Vash_the_Stampede
Уровень 11
4 сентября 2014, 12:42
10 — 2 => 8
Docktor91
Уровень 40
4 сентября 2014, 12:46
аа, тьфу ты, вы тут спор развели))))
да согласен тогда…
любые три, т.е.
такой вывод
[2,4,4,2,4,4,2,4,4,2]
Vash_the_Stampede
Уровень 11
9 ноября 2017, 13:42
Опрос
Vash_the_Stampede
Уровень 11
3 сентября 2014, 18:32
Тут был код задания. Удален мною, поскольку был неверен и занимал много места.
Vash_the_Stampede
Уровень 11
3 сентября 2014, 18:31
Не знаю, почему, но Arrays.binarySearch(new int[] { 4, 1, 0 }, 0) возвращает -1(я ожидал 2), поэтому пришлось самому искать:
public static int[] kitchen32(int[] arr) {
    final int N = arr.length; // number of cubes
    final int S = 10; // sum of three nearby cubes

    int k1 = -1;
    while (arr[++k1] == 0);
    int k2 = k1;
    while (arr[++k2] == 0);

    if (k1 % 3 == k2 % 3) {
        if (arr[k1] != arr[k2]) {
            System.out.println("Impossibile!"); // Italian
            System.exit(0);
        }
        else {
            arr[k1 + 1] = arr[k1];
        }
    }

    int[] three = new int[3];

    three[k1 % 3] = arr[k1];
    three[k2 % 3] = arr[k2];
    for (int i = 0; i < 3; i++) {
        if (three[i] == 0) {
            three[i] = S - three[0] - three[1] - three[2];
            break;
        }
    }

    System.out.println(Arrays.toString(three));

    for (int i = 0; i < N; i++) {
        arr[i] = three[i % 3];
    }

    return arr;
}