Промежуточные дроби


13

Промежуточные дроби

Соревнование:

Вам нужно будет создать код, который принимает как минимум 3 входа; 2 целых числа и «представление дроби» - какой бы тип не подходил вашему языку для представления приращений дроби) т.е. Если вы выберете строку, вход будет "1/4", или вы можете выбрать 2 дополнительных целочисленных ввода или кортеж или w / e.

Ввод может быть где угодно (STDIN, аргументы функции, из файла и т. Д.), И поэтому может выводиться (STDOUT, возвращаемое значение функции в файл и т. Д.)

Правила:

  1. Входная дробь всегда будет действительной дробью, меньше 1; пример "1/4"
  2. Второе входное целое всегда будет иметь более высокое значение, чем первое целое. То есть первое входное целое число всегда будет иметь меньшее значение, чем второе.
  3. Входные целые числа могут быть отрицательными.
  4. Выведенные дроби должны быть максимально уменьшены (упрощены)

Код должен будет выводить каждый «шаг дроби» между двумя числами с приращением входной дроби.

Код должен быть программой или функцией, как указано здесь

Пример 1:

Входные данные: -2,3,"1/2"

Выход:

 -2
 -3/2 
 -1 
 -1/2 
  0 
  1/2 
  1 
  3/2  
  2 
  5/2 
  3

Пример 2:

Входные данные: 1,2,"2/3"

Выход:

1
5/3
2

или

1
4/3
2

Примечание: подсчет может начинаться с любого направления (спасибо @Mego)

Это , поэтому выигрывает самый короткий ответ в байтах.


Можно ли взять дробь как 2 целочисленных входа, получая 4 суммарных ввода?
Мего

Я думаю, что соблюдаю ограничение на максимум 3 входа - я хотел бы также увидеть код для 4 входов
Алекс Карлсен

В таком случае, как насчет наличия списка / кортежа / массива / какого-либо другого итерируемого типа, содержащего два целых числа для третьего ввода? Это принципиально не отличается от 4 целых чисел. Также следует уточнить, что дробь не будет равна 0.
Mego

@Mego После обдумывания этого я не могу понять, почему это не должно быть разрешено. Изменено на «код, который принимает как минимум 3 входа»
Алекс Карлсен,

1
@ beaker, если вывод правильный и входной сигнал поступает как минимум от 2 целых чисел, остальное зависит от вас :) - я оставил входную часть довольно открытой, чтобы увидеть разные ответы
Алекс Карлсен

Ответы:


5

Октава, 34 30 байт

@(a,b,c)rats(union([a:c:b],b))

Теперь принимает дробь как числовое выражение, а не как отдельный числитель и знаменатель.

Образец на идеоне


1
Так почему ты не можешь использовать @(a,b,c)rats(union([a:c:b],b))?
Луис Мендо

@ LuisMendo Я могу, если математические выражения являются приемлемыми входными данными (эффективный результат 1/2в виде числового, а не строкового ввода), но я не так интерпретировал «представление дроби». Если ОП согласится, я буду рад сбрить 4 байта.
стакан

А ну понятно. Ну, я использую это в своем ответе Matlab. Так же как и Mathematica отвечает, по-видимому, если «рациональное число» не является конкретным типом данных
Луис Мендо

@ Beaker я действительно ответил
Алекс Карлсен

Код @VisualBean уже обновлен.
мензурка

11

Mathematica, 16 байт

Range@##⋃{#2}&

Безымянная функция, которая принимает два целых числа и рациональное число и возвращает список чисел, например:

Range@##⋃{#2}&[-2, 3, 1/2]
(* {-2, -(3/2), -1, -(1/2), 0, 1/2, 1, 3/2, 2, 5/2, 3} *)

Mathematica Rangeделает именно то, что задает задача, за исключением того, что она не включает верхнюю границу, если разница между нижней и верхней границей не кратна размеру шага. Поэтому мы берем Union(использование ) со списком, содержащим только верхнюю границу, которая гарантирует, что он появится ровно один раз. Обратите внимание, что результат Unionбудет отсортирован, но мы все равно хотим его отсортировать, поскольку размер шага всегда положительный. Кроме того, поскольку мы работаем с рациональными значениями, они автоматически максимально сокращаются.


10

T-SQL 2012+, 831 535 477 270 246 240 219 байт

Обратите внимание, что это одна строка - в sql нет встроенной функции для уменьшения дроби. Не может быть лучшим языком для этого типа вопроса. Он читабелен человеком (вид - по сравнению с некоторыми другими языками).

DECLARE @f INT=-5,@t INT=3,@n INT=3,@ INT=8;

WITH C as(SELECT
top((@t*@-@f*@)/@n+1)ROW_NUMBER()OVER(ORDER BY @)M
FROM sys.messages)SELECT(SELECT
IIF(V%@=0,LEFT(V/@,9),CONCAT(V/MAX(M),'/',ABS(@)/MAX(M)))FROM c
WHERE V%M=0AND @%M=0)FROM(SELECT
@f*@+@n*~-M V FROM c)k

Попробуйте онлайн


Разве язык не называется T-SQL, а не "Sqlserver"?
Дэвид Конрад

1
@DavidConrad язык TSQL, но есть разные версии sqlserver, и TSQL для этого будет работать для sqlserver 2012 из-за ключевого слова IIF. Который будет использовать ключевое слово CASE в более старых версиях. Добавил ваше предложение
t-clausen.dk

Молодец. Вы можете сохранить несколько изменив либо @nили @dна равнину @. Ваш запрос CTE для N может быть N AS(SELECT N FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))M(N))или N AS(SELECT 1N FROM sys.all_views). Учитывая, что в этом представлении почти гарантированно будет несколько сотен, вы также можете уменьшить количество перекрестных соединений. ISNULLкороче COALESCEи должен работать
MickyT

@MickyT, благодаря твоим предложениям и нескольким моим, мне удалось уменьшить длину на 296 байт,
t-clausen.dk

Отличная работа
MickyT


5

Haskell, 31 26 байт

f a b c=min[b]$a:f(a+c)b c

Ленивая оценка FTW! Демо-версия:

*Main> import Data.Ratio
*Main Data.Ratio> f (-2) 3 (1%2)
[(-2) % 1,(-3) % 2,(-1) % 1,(-1) % 2,0 % 1,1 % 2,1 % 1,3 % 2,2 % 1,5 % 2,3 % 1]
*Main Data.Ratio> f 1 2 (2%3)
[1 % 1,5 % 3,2 % 1]

(Первоначально меня соблазнили [a,a+c..b]нотации Хаскелла , но у него есть некоторые причуды, которые требуют чего-то вроде f a b c|l<-[a,a+c..b-c/2]=l++[b|last l<b]41 байта или f a b c=[x|x<-[a,a+c..],x<b]++[b]33).


Мне нравится ваше решение! Тем не менее, я думаю, что вы должны включить import Data.Ratioв свой счетчик байтов, я думаю, вы не можете использовать fбез этого, верно?
flawr

2
@flawr: хороший крайний случай: вам не нужен сам Data.Ratioпо fсебе, потому что он полиморфен для всех числовых типов. Однако, когда вы хотите вызвать его со значениями типа Ratio, вам нужен импорт. Задача требует только «создать код, который ...», а не использовать его. Я думаю, что это нормально без импорта.
Ними

1
Точнее, вам нужен только импорт для %оператора для создания тестовых фракций 1 % 2и 2 % 3. Я не обманываю здесь: вы действительно можете поместить эти 26 байтов в файл самостоятельно, запустить интерпретатор для этого модуля и получить отображаемое мной взаимодействие. (Вы могли бы даже избежать ввода import Data.Ratioв демонстрационном взаимодействии, если бы вместо этого произносили %как Data.Ratio.%.)
Anders Kaseorg

5

MATL , 16 15 байт

3$:3Gvu9X10ZGZD

Это может не сработать для очень больших знаменателей. Я надеюсь, что выходной формат является приемлемым.

Попробуйте онлайн!

3$:    % take three inputs and generate range
3G     % push third input again
v      % vertically concatenate. Gives vertical array as output 
u      % get unique elements (i.e. remove the last one if it is repeated)
9X1    % predefined literal 'rat'
0ZG    % set rational format
ZD     % display using that format

5

Рубин , 32 54 48 байт

->a,b,c{(a..b).step(c){|x|p x%1>0?x:x.to_i};p b}

Это решение основано на ответе Mego на Python и предполагает, что cэто всегда будет Rationalформат дроби Ruby. Попробуйте онлайн!

Редактировать: Исправлена ​​ошибка, когда целые числа не были представлены как целые числа. -6 байт благодаря Not That Charles и MegaTom.

Функции вызываются следующим образом:

> f=->a,b,c{(a..b).step(c){|x|p x%1>0?x:x.to_i};p b}
> f[1,4,Rational(2,3)]
1
(5/3)
(7/3)
3
(11/3)
4

(3/1) не должно быть просто 3?
edc65

Самый простой Rationalвид 3в Рубине(3/1)
Sherlock9

.step(b,c).mapследует уменьшить количество байтов здесь
не то, что Чарльз

(a==a.to_i)может быть a%1==0для -4 байта.
MegaTom

-2,3,1/2r(пример 1) печатает последние 3дважды.
Value Ink

3

Юлия, 14 байт

f(a,b,c)=a:c:b

Это похоже на ответ Mathematica, за исключением того, что диапазоны Юлии уже в желаемом формате, поэтому он еще короче. Также возвращает коллекцию чисел. Пример вывода:

11-element StepRange{Rational{Int64},Rational{Int64}}:
 -3//1,-5//2,-2//1,-3//2,-1//1,-1//2,0//1,1//2,1//1,3//2,2//1

Обратите внимание, что целые числа отображаются с 1 в знаменателе, а двойная косая черта используется для дробей. Чтобы получить результат точно так, как определено в вопросе, требуется еще немного кода:

f(a,b,c)=map(x->println(x.num,x.den<2?"":"/$(x.den)"),a:c:b)

3

Matlab с символьным инструментарием / октава с SymPy, 27 байт

Спасибо @sanchises за указание на ошибку, теперь исправленную

@(a,b,c)sym(union(a:c:b,b))

Это анонимная функция. Чтобы вызвать его, присвойте его переменной или используйте ans.

Пример:

>> @(a,b,c)sym(union(a:c:b,b))
ans = 
    @(a,b,c)sym(union(a:c:b,b))
>> ans(-2,3,1/2)
ans =
[ -2, -3/2, -1, -1/2, 0, 1/2, 1, 3/2, 2, 5/2, 3]

Это не соответствует спецификации, так как верхняя граница не всегда включена (попробуйте пример 2).
Санчизес

@sanchises Спасибо! Исправлено сейчас
Луис Мендо

Кроме того, я думаю, что cвы можете использовать, я цитирую, какой бы тип не подходил вашему языку для представления приращений дроби [...] или w / e . Я думаю, что довольно ясно, что symbolicэто логичный и разрешенный (@VisualBean может захотеть подтвердить это) выбор. Результат оператора двоеточия затем «обновляется» до symbolicмассива, что означает, что вы можете полностью избавиться от sym()вызова.
Санчизес

@sanchises Спасибо, я попросил разъяснений
Луис Мендо

2

Javascript, 108 90 86   81 байт

(a,b,n,d)=>{var s="";for(a=a*d;a<b*d;a+=n)s+=(a%d?a+"/"+d:a/d)+" ";s+=b;return s}

Анонимная функция. После присвоения именованной переменной с пробелами:

var f=(a,b,n,d)=>
{ var s="";
  for(a=a*d; a<b*d; a+=n)
    s+= (a%d ? a + "/" + d : a/d) + " ";
  s+=b;
  return s
}

Тестовые примеры:

console.log(f(1,2,1,8)); //writes:
1 9/8 10/8 11/8 12/8 13/8 14/8 15/8 2

console.log(f(-3,3,4,7)); // writes:
-3 -17/7 -13/7 -9/7 -5/7 -1/7 3/7 1 11/7 15/7 19/7 3 

Императивный подход с использованием JavaScript, без рекурсии, библиотечного или функционального программирования.


1

Smalltalk - 89 байт

На этот раз Smalltalk практически конкурентоспособен!

Number extend[p:e q:i[|h|self to:e by:i do:[:x|h:=x. x printNl].h=e ifFalse:[e printNl]]]

Звоните так:

> 2 p:5 q:1/2
2
5/2
3
7/2
4
9/2
5

> 1 p:2 q:2/3
1
5/3
2

1

R - 71 байт

Предполагается, что вы уже установили MASSпакет

f=function(x,y,z)MASS::fractions(union(seq(x,y,eval(parse(text=z))),y))

> f(1, 2, '1/3')
[1]   1 4/3 5/3   2
> f(2, 5, '1/2')
[1]   2 5/2   3 7/2   4 9/2   5

1

Pyret, 56 байт

{(b,e,n,d):link(e,map(_ / d,range(b * d, e * d))).sort()}

Принимает начало (b), конец (e), числитель (n) и знаменатель (d). Создает диапазон целых чисел, разделяет их и добавляет конец в список (путем связывания, а затем сортировки).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.