Java FizzBuzz 1 линия - PullRequest
       46

Java FizzBuzz 1 линия

0 голосов
/ 06 октября 2019

Как можно выполнить FizzBuzz упражнение в Codingbat только с помощью оператора return?

Код, который я в последний раз использовал для решения проблемы, был:

public String[] fizzBuzz(int start, int end) {
  String[] a = new String[end - start];
  for(int i = start; i < end; i++) a[i - start] = i % 15 == 0 ? "FizzBuzz" : i % 3 == 0 ? "Fizz" : i % 5 == 0 ? "Buzz" : String.valueOf(i);
  return a;
}

Моя цель - получить код, который выглядит примерно так:

public String[] fizzBuzz(int start, int end) {
  return foo;
}

Задача

Это немного более сложная версия знаменитогоПроблема FizzBuzz, которую иногда называют первой проблемой для собеседований. (См. Также: Код FizzBuzz .) Рассмотрим последовательность чисел, начинающуюся с начало и продолжающуюся до, но не включающую конец , поэтому, например, start = 1 иend = 5 дает ряды 1, 2, 3, 4. Вернуть новый массив String[], содержащий строковую форму этих чисел, за исключением кратных 3, использовать «Fizz» вместо числа, для кратных 5 использовать »Buzz ", а для кратных 3 и 5 используйте" FizzBuzz ". В Java String.valueOf(xxx) сделает строковую форму типа int или другого типа. Эта версия немного сложнее, чем обычная версия, так как вам нужно выделять и индексировать в массив, а не просто печатать, и мы меняем начало / конец вместо того, чтобы всегда делать 1..100.


Контрольные примеры

fizzBuzz(1, 6) → ["1", "2", "Fizz", "4", "Buzz"]
fizzBuzz(1, 8) → ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7"]
fizzBuzz(1, 11) → ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz"]
fizzBuzz(1, 16) → ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "FizzBuzz"]
fizzBuzz(1, 4) → ["1", "2", "Fizz"]
fizzBuzz(1, 2) → ["1"]
fizzBuzz(50, 56) → ["Buzz", "Fizz", "52", "53", "Fizz", "Buzz"]
fizzBuzz(15, 17) → ["FizzBuzz", "16"]
fizzBuzz(30, 36) → ["FizzBuzz", "31", "32", "Fizz", "34", "Buzz"]
fizzBuzz(1000, 1006) → ["Buzz", "1001", "Fizz", "1003", "1004", "FizzBuzz"]
fizzBuzz(99, 102) → ["Fizz", "Buzz", "101"]
fizzBuzz(14, 20) → ["14", "FizzBuzz", "16", "17", "Fizz", "19"]

Ответы [ 3 ]

3 голосов
/ 06 октября 2019

Не знаю точно, почему вы хотите сделать это в одном операторе возврата, но, тем не менее, здесь все идет так:

return IntStream.range(start, end)
                .mapToObj(i -> i % 15 == 0 ? "FizzBuzz" : 
                          i % 3 == 0 ? "Fizz" : i % 5 == 0 ? "Buzz" : String.valueOf(i))
                .toArray(String[]::new);
  1. IntStream.range возвращает последовательный заказ IntStream из start (включительно) до end (исключительно) с шагом 1, что точно соответствует вашему императивному подходу.
  2. mapToObj позволяет нам преобразовать IntStream в Stream<String>.
  3. toArray позволяет нам преобразовать Stream<String> в String[] для возврата.

Подробнее о IntStream API можно прочитать здесь .

1 голос
/ 06 октября 2019

Единственный способ, который я мог бы представить без каких-либо особенностей Java 8, - это некрасивое преобразование массивов в строки и строк массивов строк в массивы строк с некоторыми ... прагматическими регулярными выражениями. Но я думаю, что решение не должно быть красивым в любом случае. Тем не менее, он проходит все тестовые случаи, поэтому он достигает всех целей, которые могут быть достигнуты с помощью разработки, основанной на тестировании ...

Никогда не пишите ничего, даже отдаленно напоминающего это в реальной жизни!

import java.util.Arrays;

public class OneLineFizzBuzz
{
    public static void main(String[] args)
    {
        OneLineFizzBuzz f = new OneLineFizzBuzz();
        String[] result = f.fizzBuzz(1000, 1006);
        System.out.println(Arrays.toString(result));

        check(f.fizzBuzz(1, 6), new String[]{"1", "2", "Fizz", "4", "Buzz"});
        check(f.fizzBuzz(1, 8), new String[]{"1", "2", "Fizz", "4", "Buzz", "Fizz", "7"});
        check(f.fizzBuzz(1, 11), new String[]{"1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz"});
        check(f.fizzBuzz(1, 16), new String[]{"1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "FizzBuzz"});
        check(f.fizzBuzz(1, 4), new String[]{"1", "2", "Fizz"});
        check(f.fizzBuzz(1, 2), new String[]{"1"});
        check(f.fizzBuzz(50, 56), new String[]{"Buzz", "Fizz", "52", "53", "Fizz", "Buzz"});
        check(f.fizzBuzz(15, 17), new String[]{"FizzBuzz", "16"});
        check(f.fizzBuzz(30, 36), new String[]{"FizzBuzz", "31", "32", "Fizz", "34", "Buzz"});
        check(f.fizzBuzz(1000, 1006), new String[]{"Buzz", "1001", "Fizz", "1003", "1004", "FizzBuzz"});
        check(f.fizzBuzz(99, 102), new String[]{"Fizz", "Buzz", "101"});
        check(f.fizzBuzz(14, 20), new String[]{"14", "FizzBuzz", "16", "17", "Fizz", "19"});        
    }
    private static void check(String[] fizzBuzz, String[] strings)
    {
        boolean passed = Arrays.equals(fizzBuzz, strings);
        System.out.println(Arrays.toString(fizzBuzz) + " passed? " + passed);
        if (!passed)
        {
            System.out.println("Whoopsie...");
        }
    }

    public String[] fizzBuzz(int start, int end)
    {
        return (start == end ? ""
            : (start % 15 == 0 ? "FizzBuzz"
                : start % 3 == 0 ? "Fizz"
                    : start % 5 == 0 ? "Buzz" : String.valueOf(start))
                + Arrays.toString(fizzBuzz(start + 1, end)))
                    .replaceAll("\\]", "").split("\\[|,\\s*");
    }
}
0 голосов
/ 06 октября 2019
  1. убедитесь, что у вас JDK 8 (в противном случае этот код не будет работать)

  2. Используя IntStream.range, вы можете генерировать целые числа. и когда у вас есть множество цифр, вы должны отобразить их соответственно. (в этом случае мы должны отобразить их в String [] и проверить на кратность 3, кратность 5 и кратность 3 и 5) Теперь, для остальных чисел Используя String.valueof (), мы можем добавить их в массив.

Примечание: убедитесь, что FIZZBUZZ находится сверху, так как это оператор if, только один из них выполняется.

    public static String[] foo(int start, int end) {
        return IntStream.range(start, end).mapToObj(i-> ( 
        i%5==0 && i%3==0 ) ? "FIZZBUZZ": 
        i%3==0 ? "FIZZ":
        i%5==0 ? "BUZZ": 
        String.valueOf(i)).toArray(String[]::new);
}
...