Отдел не очень маленьких чисел


15

Написать программу или функцию , которая принимает в положительных целых числах a, bи c, и печатает или возвращаются a/bк cзнакам после запятой, используя операции + - * /% [добавить, вычитание, умножение, деление, модулирует] на положительных целых числах: вы можете использовать все , что ваш язык позволяет, но не на числах с плавающей запятой. Диапазон a, b, c будет диапазоном, разрешенным для целых чисел без знака в вашем языке. Числовой результат будет усечен до последней цифры для печати (поэтому нет round).

Это означает, что если ваш язык не имеет целочисленного типа (только с плавающей точкой), вы можете участвовать, используя эти числа с плавающей точкой только как положительные целые числа. Ключом к этому упражнению было бы написать функцию, которая находит цифры в делении с плавающей запятой, используя только операцию + - * /% для [unsigned] целых чисел.

Примеры

  • print(1,2,1) будет печатать 0.5
  • print(1,2,2) будет печатать 0.50
  • print(13,7,27) будет печатать 1.857142857142857142857142857
  • print(2,3,1) будет печатать 0.6
  • print(4,5,7) будет печатать 0.8000000
  • print(4,5,1) будет печатать 0.8
  • print(9999,23,1) будет печатать 434.7
  • print(12345613,2321,89) напечатает, если ваш язык имеет 32-битный без знака 5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466

Самый короткий код в байтах побеждает. Извините, если это кажется непонятным ... Я тоже не знаю языков, плохо помню слова ... Лучше иметь одну ссылку на Ideone.com или другое место, чтобы легко найти ответ, особенно для проверить некоторые входные данные, отличные от предложенных.


1
Каков диапазон целых чисел a, b, c?
Тон Хоспел

@Ton Hospel диапазон a, b, c будет диапазоном, допускающим целое число без знака на вашем языке: например, если это 32-разрядное без знака, оно будет равно 0..0xFFFFFFFF, но если c> = 0xFFFFFFF, такой большой результат будет быть немного медленным ...
RosLuP

2
Это функция округления - или, точнее, она должна быть функцией округления, чтобы быть правильно заданной. В настоящее время неясно, каким будет правильный ответ, например (1,2,0). См. Meta.codegolf.stackexchange.com/a/5608/194
Питер Тейлор,

1
Извините за повторное открытие этого вопроса; Я думаю, что он почти готов к открытию, за исключением проблемы, на которую указал Питер Тейлор. Каков вывод fo (1,2,0)?
ETHproductions

2
На самом деле (1,2,0)должно быть не имеет значения, так 0как не является положительным целым числом. И я бы предпочел, чтобы c так и оставалось, потому что я предпочел бы не думать о добавлении .или нет
Тон Хоспел

Ответы:


5

05AB1E , 17 13 11 19 14 байтов

Ввод в форме b, a, c.
Сохранено 5 байтов благодаря Грими .

‰`¹+I°*¹÷¦'.sJ

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


Я только что попробовал это онлайн с вводом 13,7,27 и ответ не правильный
Матье Ж.

@shigazaru: возвращает тот же результат, что и в тестовых примерах . Вы заметили порядок входов b,a,c?
Эминья,

Я пробую кнопку «Попробовать онлайн», где есть это разделение: 12345613/2321 с 89 цифрами, но в результате получается что-то вроде 5319,922 ... вместо 5319.0922 ...
РосЛуП

1
15:‰`I°*¹÷I°+¦'.sJ
Grimmy

2
14:‰`¹+I°*¹÷¦'.sJ
Grimmy

4

Haskell, 87 байт

(a#b)c|s<-show$div(a*10^c)b,l<-length s-c,(h,t)<-splitAt l s=['0'|l<1]++h++['.'|c>0]++t

Пример использования: (13#7)27-> "1.857142857142857142857142857".

23 байта для обработки c==0регистра и использования начального нуля вместо таких вещей, как .5.

Как это работает: умножить aна 10^c, разделить на b, превратить в строку, разделить, где .необходимо вставить, соединить обе части с .промежуточным и исправить крайние случаи.


4

Perl 6 ,  58 57 55  48 байт

{(($^a.FatRat/$^b*10**$^c).Int.FatRat/10**$c).base(10,$c)}
{(Int($^a.FatRat/$^b*10**$^c).FatRat/10**$c).base(10,$c)}
{base Int($^a.FatRat/$^b*10**$^c).FatRat/10**$c: 10,$c}
{base ($^a*10**$^c div$^b).FatRat/10**$c: 10,$c}

Что довольно досадно, так это то, что его можно было бы сократить до того, {($^a.FatRat/$^b).base(10,$^c)}чтобы было разрешено округление до ближайшего значения.

Объяснение:

# bare block lambda with 3 placeholder parameters 「$^a」, 「$^b」 and 「$^c」
{
  (
    (

      # create an Int containing all of the digits we care about
      $^a * 10 ** $^c div $^b

    ).FatRat / 10**$c  # turn it into a Rational

  ).base( 10, $c )     # force it to display 「$c」 digits after the decimal point
}

Я не знаком с perl6, но разве (...).FatRat / 10**$xэто не подразделение Rational? Вам разрешено делить только целые числа.
Ними

@nimi a Rational - это класс с двумя Ints .
Брэд Гилберт b2gills

Математические операторы разрешены только для целочисленных типов, а не для других числовых типов. Цитата: «Ключ к этому упражнению ... написать функцию ... используя только операцию + - * /% для [беззнаковых] целых чисел».
Ними

@nimi Так что, если я напишу переопределение Rational и не добавлю, does Realили does Numericэто будет разрешено? Что, если я дополню (исправление обезьяны) существующий класс, чтобы удалить эти роли, это будет разрешено?
Брэд Гилберт b2gills

Не знаю Я прочитал спецификацию, как сказано выше: +-*/%только с простыми целочисленными типами. «обычное целое» с точки зрения функциональности (прежде всего: целочисленного деления), а не внутреннего представления. Как вы думаете, разрешено ли использовать программную библиотеку с плавающей точкой, которая (несмотря на название) также использует только целые числа для внутреннего представления?
Ними

3

Perl, 55 байт

Включает +3 для -p

Дайте a и b в одной строке на STDIN, c на следующей

division.pl
1 26
38
^D

division.pl:

#!/usr/bin/perl -p
eval'$\.=($_/$&|0)."."x!$\;$_=$_%$&.0;'x(/ .*/+<>)}{

$_/$&немного спорно. Я на самом деле хочу целочисленное деление там, но Perl не имеет этого без загрузки специальных модулей. Так что это временно нецелое число, которое я затем немедленно усекаю (использую |0), так что я получаю целое число, которое даст целочисленное деление. Его можно переписать так ($_-$_%$&)/$&, чтобы даже временно не иметь нецелочисленного значения (хотя внутренне оно все еще было бы с плавающей точкой)


Не могли бы вы использовать $-его только для int? (Я думаю, что есть строгие ограничения на микс / макс, и я уверен, что вы уже рассмотрели это, но хотя это стоит проверить!)
Dom Hastings

@DomHastings После деления с плавающей точкой все равно будет усеченным. В Perl просто нет целочисленного деленияuse integer
Тон Хоспел

Ах, так это просто замаскировано $-, приятно знать. Благодарность!
Дом Гастингс

3

JavaScript (ES6), 55 50 байт

f=(a,b,c,d=".")=>~c?(a/b|0)+d+f(a%b*10,b,c-1,""):d

(a/b|0)выполняет деление с плавающей запятой, но немедленно приводит к целому числу. Пожалуйста, дайте мне знать, если это не разрешено.


3

PHP, 187 байт

работает со строками для числителя, которые могут быть значения int больше, чем PHP_INT_MAX

list(,$n,$d,$c)=$argv;$a=str_split($n);while($a){$n.=array_shift($a);if($n>=$d||$r)$n-=$d*$r[]=$n/$d^0;}if(!$r)$r[]=0;if($c)$r[]=".";while($c--){$n*=10;$n-=$d*$r[]=$n/$d^0;}echo join($r);

У меня нет другого шанса, тогда 13/7 сокращается до 1.8571428571429, и я достигаю, поэтому не тестовый случай с 27 знаками после запятой

Таким образом, 36 байтов не допускается

<?=bcdiv(($z=$argv)[1],$z[2],$z[3]);

Разделение поплавка не разрешено согласно OP
Maltysen

@ Maltysen Извините, я делаю откат. Я так боялся найти более короткое решение, что я не признаю, что оно противоречит спецификации.
Йорг Хюльсерманн

2

Pyth - 21 19 18 16 14 байт

Будет просматривать формат ввода, который может сохранить кучу.

j\.c`/*E^TQE]_

Тестовый пакет . (PS 27 не заканчивается онлайн, поэтому я сделал 10).


@Emigna И при этом это не обязательно, так 0как не является положительным целым числом (хотя операционная система продолжает добавлять примеры с c=0)
Тон Хоспел

@TonHospel: Ах, действительно. Я смотрел на примеры. Тогда я могу сократить свой ответ :)
Emigna

Не работает с числами, которые имеют начальный 0 после десятичной точки, например от 2/21 до 10 десятичных знаков.
Emigna

2/21 с 10 цифрами печатают только 9 цифр после запятой
РосЛюП

2/21 с 10 цифрами, как говорит Эминья, вместо 0,09 ... печать 0,9 ...
РосЛюП

2

JavaScript (ES6),  64  62 59 байт

Сохранено 2 байта благодаря ETHproductions.

Включенное деление всегда приводит к целому числу.

f=(a,b,n,s)=>~n?f((q=(a-a%b)/b,a%b*10),b,n-1,s?s+q:q+'.'):s

console.log(f(13,7,27))


Будет ли пропуск mвообще работать? f=(a,b,n,s)=>n+1?f((q=(a-a%b)/b,a%b*10),b,n-1,s?s+q:q+'.'):sсоставляет 60 байтов.
ETHproductions

@ETHproductions - Действительно. Благодарность!
Арно

2

Java 7, 105 байт

import java.math.*;String c(int...a){return new BigDecimal(a[0]).divide(new BigDecimal(a[1]),a[2],3)+"";}

Ungolfed & тестовый код:

Попробуй это здесь.

import java.math.*;
class M{
  static String c(int... a){
    return new BigDecimal(a[0]).divide(new BigDecimal(a[1]), a[2], 3)+"";
  }

  public static void main(String[] a){
    System.out.println(c(1, 2, 1));
    System.out.println(c(1, 2, 2));
    System.out.println(c(13, 7, 27));
    System.out.println(c(2, 3, 1));
    System.out.println(c(4, 5, 7));
    System.out.println(c(4, 5, 0));
    System.out.println(c(9999, 23, 0));
    System.out.println(c(12345613, 2321, 89));
  }
}

Выход:

0.5
0.50
1.857142857142857142857142857
0.6
0.8000000
0
434
5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466

Я не думаю, что это действительно, потому что это по существу деление с плавающей точкой, хотя оно называется divideи нет /.
corvus_192

@ corvus_192 Другой удаленный Java-ответ, который был опубликован позже меня, имел причину, которую я скопирую и вставлю здесь ( ссылка на это объяснение приведена в @SocraticPhoenix ): « Как это работает: Java BigDecimals реализованы как BigIntegers с масштабом. Это технически плавающая точка, однако объекты BigInteger и BigDecimal используют только intтип для хранения числового значения. (Разве это не круто? BigInteger - это int[]цифра. Например, {1,2,5} в базе 10 равен 125. I Я не уверен, в какой базе на самом деле находятся цифры BigInteger, но я бы предположил, что это больше, чем 10. "
Кевин Круйссен

2

Рубин, 67 байт

->(a,b,c){('0'+(a*10**c/b).to_s).gsub(/^0*(.+)(.{#{c}})$/,'\1.\2')}

если я сделаю это функцией для выполнения тестовых случаев выше

def print(a,b,c); ('0'+(a*10**c/b).to_s).gsub(/^0*(.+)(.{#{c}})$/, '\1.\2'); end
 => :print 
print(1,2,1)   # would print 0.5
 => "0.5" 
print(1,2,2)   # would print 0.50
 => "0.50" 
print(13,7,27) # would print 1.857142857142857142857142857
 => "1.857142857142857142857142857" 
print(2,3,1)   # would print 0.6
 => "0.6" 
print(4,5,7)   # would print 0.8000000
 => "0.8000000" 
print(4,5,1)   # would print 0.8
 => "0.8" 
print(9999,23,1) # would print 434.7
 => "434.7" 
print(12345613,2321,89) # would print if your Language has 32 bit unsigned 5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466
 => "5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466" 
"('0'+(a*10**c/b).to_s).gsub(/^0*(.+)(.{#{c}})$/, '\1.\2')".length
 => 52 

Добро пожаловать в код гольф! Для большинства языков, когда вы определяете функцию, вы должны определить ее полностью, и вы не можете полагаться на то, что есть предопределенные переменные, подобные этой. В Ruby самый короткий способ определить лямбду - ->a,b,c{...}это заменить эллипсы своим кодом. (Фактическое присвоение переменной не требуется консенсусом.)
Value Ink

спасибо, у меня было неправильное впечатление, что другие упустили эту часть ... но ты прав. Я только добавил это.
Матье Ж.

2

Ракетка 203 байта

(let*((s(~r(/ a b)#:precision c))(sl(string-split s "."))(s2(list-ref sl 1))(n(string-length s2)))
(if(< n c)(begin(for((i(- c n)))(set! s2(string-append s2 "0")))(string-append(list-ref sl 0)"."s2))s))

Ungolfed:

(define (f a b c)
  (let* ((s (~r(/ a b)#:precision c))
         (sl (string-split s "."))
         (s2 (list-ref sl 1))
         (n (string-length s2)))
    (if (< n c)
        (begin 
          (for ((i (- c n)))
            (set! s2 (string-append s2 "0")))
          (string-append (list-ref sl 0) "." s2))
        s )))

Использование:

(f 7 5 3)
(f 1 2 1) 
(f 1 2 2) 
(f 13 7 27)

Выход:

"1.400"
"0.5"
"0.50"
"1.857142857142857142857142857"

Другой метод (неправильный ответ здесь):

(real->decimal-string(/ a b)c)

Боюсь, что это неверно, потому что real->decimal-stringожидает realзначение в качестве первого аргумента, /как и деление с плавающей запятой, что не разрешено в этой задаче. Также: real->decimal-stringраунды ( (f 1 6 7)-> 0.1666667) вместо усечения.
Ними

Спасибо за наблюдения. Я скоро исправлю код.
rnso

1

q, 196 байт

w:{((x 0)div 10;1+x 1)}/[{0<x 0};(a;0)]1;{s:x 0;m:x 2;r:(10*x 1)+$[m<0;{x*10}/[-1*m;a];{x div 10}/[m;a]]mod 10;d:1#.Q.s r div b;($[m=-1;s,".",d;$[s~,:'["0"];d;s,d]];r mod b;m-1)}/[c+w;("";0;w-1)]0

Для запуска: сначала установите a, b, c.


1

Ржавчина, 114 байт

fn print(mut a:u32,b:u32,c:u32){let mut p=||{print!("{}",a/b);a=a%b*10};p();if c>0{print!(".")}for _ in 0..c{p()}}

тестовый код:

fn main() {
    print(1, 2, 1);    println!(""); // should print 0.5
    print(1, 2, 2);    println!(""); // should print 0.50
    print(13, 7, 27);  println!(""); // should print 1.857142857142857142857142857
    print(2, 3, 1);    println!(""); // should print 0.6
    print(4, 5, 7);    println!(""); // should print 0.8000000
    print(4, 5, 0);    println!(""); // should print 0
    print(9999, 23, 0);println!(""); // should print 434
    print(12345613,2321,89); println!("\n");  // 5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466
}

1

PHP, 89 байт

list(,$a,$b,$c)=$argv;for($o=intdiv($a,$b).'.';$c--;)$o.=intdiv($a=10*($a%$b),$b);echo$o;

intdiv () введен в php 7, поэтому он требует этого. php 7.1 позволит мне изменить list () на [] и сэкономит 4 байта.

использовать как:

php -r "list(,$a,$b,$c)=$argv;for($o=intdiv($a,$b).'.';$c--;)$o.=intdiv($a=10*($a%$b),$b);echo$o;" 1 2 1

заменить $o.=intdiv($a=10*($a%$b),$b);на $o.=($a=10*($a%$b))/$b^0;сэкономит 4 байта.
Йорг Хюльсерманн

Первоначально я собирался воспользоваться этим советом (я отредактировал ответ и все остальное), но потом подумал, что это деление с плавающей запятой, а затем приведение к int, поэтому для увеличения длины <10% я бы предпочел полностью придерживаться спецификаций вопрос.
user59178

1

C #, 126 байт

(a,b,c)=>{var v=a*BigInteger.Parse("1"+new string('0',c))/b+"";return v.PadLeft(c+1,'0').Insert(Math.Max(1,v.Length-c),".");};

Полная программа с тестовыми примерами:

using System;
using System.Numerics;

namespace DivisionOfNotSoLittleNumbers
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<BigInteger,BigInteger,int,string>f= (a,b,c)=>{var v=a*BigInteger.Parse("1"+new string('0',c))/b+"";return v.PadLeft(c+1,'0').Insert(Math.Max(1,v.Length-c),".");};

            //test cases:
            Console.WriteLine(f(1,2,1));    //0.5
            Console.WriteLine(f(1,2,2));    //0.50
            Console.WriteLine(f(13,7,27));  //1.857142857142857142857142857
            Console.WriteLine(f(2,3,1));    //0.6
            Console.WriteLine(f(4,5,7));    //0.8000000
            Console.WriteLine(f(4,5,1));    //0.8
            Console.WriteLine(f(9999,23,1));    //434.7
            Console.WriteLine(f(12345613,2321,89)); //5319.09220163722533390779836277466609220163722533390779836277466609220163722533390779836277466
            Console.WriteLine(f(2,3,1));    //0.6
            Console.WriteLine(f(4,5,2));    //0.80
        }
    }
}

Целочисленное деление реализовано. Можно использовать числа любого размера, в зависимости от BigIntegerтипа данных ( System.Numericsтребуется импорт ). Параметр подсчета цифр cограничен 2 ^ 31-1, однако он должен содержать более чем достаточно цифр.


1

Groovy ( 78 77 42 байта)

{a,b,n->Eval.me(a+'.0g').divide(b, n, 1)}​

объяснение

Eval.me(a+'.0g');- Преобразование из целочисленного ввода в ввод BigDecimal. В Groovy BigDecimal обозначение является двойным обозначением с добавлением G или g. Я мог бы также использовать конструктор, new BigDecimal(it)но это сохранило байт.
.divide(b, n, 1)- Разделить на b с точностью n, режим округления наполовину.

Попробуйте это здесь: https://groovyconsole.appspot.com/script/5177545091710976


Но BigDecimal поддерживает операцию с плавающей запятой, которая, если я не ошибаюсь, я считаю, было указано, что запрещено для этого упражнения.
Матье Ж.

1

Пакетный, 122 байта

@set/as=%1/%2,r=%1%%%2
@set s=%s%.
@for /l %%a in (1,1,%3)do @set/ad=r*10/%2,r=r*10%%%2&call set s=%%s%%%%d%%
@echo %s%

1

Mathematica, 50 байтов

StringInsert[ToString@Floor[10^# #2/#3],".",-#-1]&

Без имени функция трех аргументов (которые упорядочены c, a, bчтобы сохранить байты где - то), который возвращает строку. Он умножается a/bна 10^c, принимает наибольшую целочисленную функцию, затем преобразуется в строку и вставляет десятичную точку в соответствующем месте. Жаль, что имена функций не короче.


1

Python 3, 62 байта

a,b,c=map(int,input().split());print("{:.{1}f}".format(a/b,c))

Попробуйте здесь

* Примечание : repl.it использует более старую версию Python 3 , которая требует указания всех индексов полей, то "{:.{1}f}"есть "{0:.{1}f}"вместо этого будет 63 байта в repl.it

Как пользоваться

Введите все три значения с пробелами между ними. т. е. ввод 1 2 1даст результат0.5

объяснение

input().split(): Получает пользовательский ввод и разбивает его на список с разделителем (пробел)

a,b,c = map(int,XX): Отображает переменные в значения, указанные пользователем с типом int

"{:.{1}f}".format(a/b,c): Форматирует строку для отображения результата деления и заменяет {1}наc установить десятичное место отображаемой строки

print(XX): печатает предоставленную строку


1

Python 3 , 58 байт

lambda a,b,c:(lambda s:s[:-c]+"."+s[-c:])(str(a*10**c//b))

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

Это с точностью до указанного числа десятичных знаков до тех пор, пока a * 10 ** c не слишком большой.

Я пробовал Python 2, чтобы сократить str(...)до, `...`но Python 2 вставляет Lв конце, если он слишком велик, поэтому проверка на это займет намного больше байтов, чем стоит.


1

Stax , 13 байт

ä·oαì█↕▬AS¥é▼

Запустите и отладьте его

Аргументы принимаются по c a bпорядку.


Проблема могла бы быть в случае «print (9999,23,1)», результатом печати в посте является «434,7», в то время как ваш результат кажется «4,7» таким же, как в последнем случае: 5319.092201etc вместо 9.092201etc
RosLuP

Я не согласен ... Я проследовал сегодня утром по вашей ссылке, и результат для дела "print (9999,23,1)" в вашем функциональном порядке был 4,7, а не 434,7
РосЛюП

@RosLuP: я изменил подход. Результат теперь правильно `434,7`. Я также уменьшил размер на байт в процессе.
рекурсивный

0

C 67 байт

h(a,b,i){int j=!i;for(;printf(j++?"%u":"%u.",a/b),i--;a=10*(a%b));}

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

В какой-то предыдущей версии, я думаю, была ошибка чтения памяти из-за присвоения программе ... Спасибо, потолок и все ...


@ceilingcat ок, спасибо
РосЛюП

Мне нравится последний 69 байтов
RosLuP


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