Kontrol Dışı Yuvarlama Hataları


14

Arka fon

Kısa bir süre önce küçük bir muhasebe firması tarafından işe alındınız. Muhasebe dünyası sizin için biraz yabancıdır, bu nedenle tüm profesyonel yönergelere uyup uymadığınızdan emin değilsiniz. Özellikle, tüm bu sayıları ne zaman yuvarlamanız gerektiğini ve hangi yönde yuvarlamanız gerektiğini bilmiyorsunuz, bu yüzden çoğu zaman kanatlandırıyorsunuz ve en iyisini umuyorsunuz.

Giriş

Girişiniz, basit bir hesaplamayı temsil eden tek bir dizedir. Karakterler tarafından sınırlanan bazı negatif olmayan tamsayılar içerir +-*/. Dize soldan sağa okunur ve normal öncelik kuralları yok sayılır, yani "23+1*3/4""23 ile başla, 1 ekle, 3 ile çarp ve 4 ile böl", sonuç 18 olur. Girdi ile başlayan sayılar içermez 0( 0kendisi hariç ) veya sıfıra bölme.

Çıktı

Hesaplamanın her aşamasında, sonucu en yakın tamsayıya yukarı veya aşağı yuvarlayabilir veya olduğu gibi tutabilirsiniz. Son olarak, bir tamsayı sonucu elde etmek için yukarı veya aşağı yuvarlarsınız. Çıktınız, böyle bir hesaplamadan kaynaklanabilen, yinelenen ve yinelenmeyen tamsayıların listesidir.

kurallar

Tam bir program veya bir işlev yazabilirsiniz. En düşük bayt sayısı kazanır ve standart boşluklara izin verilmez.

Test Durumları

"42" -> [42]
"2+0+4-0" -> [6]
"23+1*3/4" -> [18]
"5/2" -> [2,3]
"5/2+7/3*6-1" -> [17,18,19,23]
"23/2/2*30-170/3" -> [-7,-6,-2,-1,0,1,3,4]
"1/3*2*2*2*2*2*2" -> [0,16,20,21,22,24,32,64]
"1/3*9" -> [0,3,9]

Program olası tüm girişler için (sayı boyutundan bağımsız olarak), sınırlı boyut girişinde veya sadece test senaryolarında mı çalışmak zorunda?
orlp

@orlp En azından tüm girdi sayıları ve ara sonuçlar, örneğin 10 milyon mutlak değerin altında olduğunda çalışmalıdır. Sonuçta muhasebe şirketi küçük.
Zgarb

1/3*9Kayan nokta sayıları kullanırsanız başarısız olabilecek test durumunu not edin .
Claudiu

@Claudiu Teşekkürler, meydan okumaya ekledim.
Zgarb

Yanıtlar:


4

J, 84 bayt

1 elemanlı bir listeden başlayarak, fonksiyon bir sonraki ifadeyi değerlendirip yukarı ve aşağı yuvarlak kopyalar ekleyerek listede olası tüm ara numaraları tutar.

Daha fazla golf olacak ve yarın açıklama ekleyecek. Daha fazla golf için belirgin yollar bulamıyorum.

f=.3 :'/:~~.<.>((,>.,<.)@".@(":@],''x'',;@[))&.>/|.(>@{.;_2<\}.);:y rplc''/'';''%'''

Tüm testleri geçer.

Kullanımı:

   f '1/3*2*2*2*2*2*2'
0 16 20 21 22 24 32 64
   f '1/3*9'
0 3 9

Burada deneyin.


Onlarla şamandıralar yerine rasyonel olarak nasıl başa çıkıyorsunuz - bu J'de yerleşik mi? (J noob'u burada tamamlayın)
Claudiu

@Claudiu Her değerlendirmede mektubu xlistenin sonuna ekleyerek genişletilmiş hassas sayıları (bu durumda gerekçeler) zorlarım .
randomra

3

Python 2, 220 karakter

import re,sys,math as m,fractions as f
X=f.Fraction
M=map
F=['+']+re.split("(\D)",sys.argv[1])
r=[X(0)]
while F:U=[eval('f.'+`n`+F[0]+F[1])for n in r];r=M(X,U+M(m.floor,U)+M(m.ceil,U));F=F[2:]
print sorted(set(M(int,r)))

Olası tüm sayıların bir listesini tutar ve her adımda, kopyalar olsa bile listedeki her sayı için üç sayı üretir. Dolayısıyla, çalışma zamanı karmaşıklığı üsteldir. Ancak, bu küçük örnekler için anında çalışır. Sonunda dupes çıkarılır.

fractions.FractionTam bölme yapmak için, kayan nokta hatalarından kaçınmak için kullanır .

Performansı önemli ölçüde artırmak için 5 karakter ( r=map(X,g)-> r=set(map(X,g))) ekleyin .


İşte başlamak için kolay bir golf: \Dbasamak olmayan eşleşmeler için önceden tanımlanmış bir karakter sınıfı
Sp3000

@orlp: Şimdi düzeltildi! (Sanırım ..)
Claudiu

@Claudiu: ya r"(\D)"ya olmalı "(\\D)". Ayrıca, Python 3 kullanıyorsanız, dizine eklemeyi Fyıldızlı atama ile değiştirebilirsiniz , örneğin:, ve yerine ve A,B,*F=Fkullanın Ave kurtulabilirsiniz . BF[0]F[1]F=F[2:]
Mac

@Mac: "\D"zaten çalışıyor ve daha kısa. Bu geçerli bir kaçış dizisi değil, bu yüzden Python sadece \ ve Dkelimesini içeriyor . İyi Python3 ipucu aslında, ben kontrol edeceğim, ama ben backticks değiştirmek repr()ve mapsonucu bir listeye dönüştürmek zorunda kalacağım . Yıldızlı görev Python 2 olsaydı bir şey ..
Claudiu

2

Python, 421 370 354 bayt

Üzgünüm, lütfen benimle kal. Python için gerçekten yeniyim (sadece fractiosn'u destekleyen bir dil arıyordum) ve kodu kısaltmak için bildiğim birkaç hileyi kullandım ama neredeyse yarısı büyüklüğünde bir python çözümü olduğunu düşünüyoruz. Çok şey öğrendim ve yine de sunacağımı düşündüm =)

@ Kirbyfan64sos ve @Zgarb sayesinde yeni sürüm

from fractions import*
from math import*
import re,operator as z
s=input()
N=re.split(r'[\*\/\-\+]',s)
O=re.split(r'[0-9]+',s)[1:-1]
d={'+':z.add,'-':z.sub,'*':z.mul,'/':z.truediv}
l=[int(N[0])]#list of inters up to now
for i in range(len(O)): #iterate over all operations
    n=set()
    for f in l:
        f=d[O[i]](f,Fraction(int(N[i+1])))
        n.update([floor(f),ceil(f),f])
    l=n
print(set(map(floor,n)))

Eski versiyon

from fractions import Fraction as F
from math import floor,ceil
import re
s=input()
N=re.split(r'[\*\/\-\+]',s)   #Numbers
O=re.split(r'[0-9]+',s)[1:-1] #Operators
l=[int(N[0])]
for i in range(len(O)): #Iterate over all operators
    n=set()
    for f in l:           #Iterate over all possible numbers
        g=F(int(N[i+1]))
        o=O[i]
        if o=='/':
            f/=g
        elif o=='*':
            f*=g
        elif o=='-':
            f-=g
        else:
            f+=g
        n.add(floor(f))  #Add all possible numbers to a new set 
        n.add(ceil(f))   # the 'set' structure prevents from having multiple copies
        n.add(f)         # which is a really nice feature
    l=n                #repeat
print(set([floor(k) for k in n])) #also remove the unrounded ones

Birincisi, bazı boşluk girintilerini sekmelerle değiştirebilirsiniz (genellikle berbat, ancak kod golfünde iyi çalışır: bir tab == 1 karakter). Birkaç ifs ( d={'+': operator.add, '-': operator.sub, ...}; d[op](a, b)) yerine bir dikte de kullanabilirsiniz . Ayrıca, [floor(k) for k in n]kısaltılabilir map(floor, n)ve n.addaramalar olabilir n.extend([floor(f), ceil(f), f]).
kirbyfan64sos

Vay canına çok teşekkür ederim, bunları uygulamaya çalışacağım! Girintileri zaten sekme olarak saydım, ancak bunları burada boşluklara dönüştürmek zorunda kaldım.
flawr

Sadece tek boşluklar da kullanabilirsiniz; çalışmalılar.
kirbyfan64sos

Görebildiğim kadarıyla, Fsadece bir kez kullanıyorsunuz, böylece yapabilir from fractions import*ve bazı baytları kaydedebilirsiniz. İle aynı math. Etraftaki boşlukları çıkarın, =gereksizdirler. Ayrıca, girişi ssabit kodlama yerine atamalısınız .
Zgarb

@flawr İsteğe bağlı tüm alanları kaldırın. Ayrıca, herhangi bir girişi kabul edebilmeniz gerekir . Bunun s=input()yerine s = "1/3*9"yorumlarınızı kaldırın vb.
Kullanın

1

Mathematica, 134

Union@Flatten@{Floor@#,Ceiling@#}&@ToExpression@StringReplace[#,x:("+"|"-"|"*"|"/"~~NumberString):>"//{Floor@#,#,Ceiling@#}"~~x~~"&"]&

0

MATLAB, 283 karakter

function[u]=w(s)
s=[' ' strsplit(regexprep(s,'\D',' $& '))];s=reshape(s,[2,size(s,2)/2]);o=s(1,:);d=cellfun(@str2num,s(2,:));a=d(1);for n=2:size(o,2)switch o{n}case'+';a=a+d(n);case'-'a=a-d(n);case'/'a=a/d(n);case'*'a=a*d(n);end;a=[ceil(a);a;floor(a)];end;u=unique(a(mod(a,1)==0))end

Ungolfed:

function [u] = WingitRound(i)
    i=[' ' strsplit(regexprep(i,'\D',' $& '))];
    i=reshape(i,[2,size(i,2)/2]);

    o=i(1,:);
    n=cellfun(@str2num,i(2,:));

    a=n(1);

    for n=2:size(o,2)
        switch o{n}
            case '+'
                a = a + n(n);
            case '-'
                a = a - n(n);
            case '/'
                a = a / n(n);
            case '*'
                a = a * n(n);
        end
        a = [ceil(a);a;floor(a)];
    end

    u=unique(a(mod(a,1)==0)));
end

Bunu yazarken, yazmayı bitirdikten sonra ekleyeceğim, bunu yapmanın daha kısa bir yolu olduğunu fark ettim.


0

VBA, 347 bayt

Function OoCRE(inp As String)
ct = 0
i = 1
Do While i < Len(inp)
c = Mid(inp, i, 1)
If Not IsNumeric(c) Then
ct = ct + 1
If ct = 2 Then
inp = Round(Application.Evaluate(Left(inp, i - 1))) & Right(inp, Len(inp) - (i - 1))
i = InStr(1, inp, c)
ct = 1
End If
End If
OoCRE = Round(Application.Evaluate(inp))
i = i + 1
Loop
End Function

1
Burada yapılması gereken çok şey var, öncelikle gereksiz boşlukları kaldırmak ve daha kısa değişken isimlerini seçmek
cat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.