3 से विभाज्यता के लिए सर्किट निर्माण


12

टीसीएस में एक बूलियन सर्किट मूल रूप से एक डीएजी है जिसमें एंड, या नॉट गेट्स शामिल हैं, और जो ज्ञात है कि "कार्यात्मक पूर्णता" है वे सभी संभावित कार्यों की गणना कर सकते हैं। उदाहरण के लिए यह एक ALU में मूल सिद्धांत है ।

चुनौती: यह निर्धारित करने के लिए एक सर्किट बनाएं कि क्या 8-बाइनरी-अंकों की संख्या 3 से विभाज्य है और किसी तरह अपने परिणाम की कल्पना करें (यानी किसी तरह की तस्वीर में)

मतदाताओं के लिए निर्णायक मानदंड इस पर आधारित है कि क्या सर्किट उत्पन्न करने के लिए कोड मनमाने ढंग से आकार की संख्याओं का सामान्य रूप से उपयोग करता है , और क्या एल्गोरिदम-निर्मित विज़ुअलाइज़ेशन कॉम्पैक्ट / संतुलित है, लेकिन फिर भी मानव-पठनीय (यानी हाथ की व्यवस्था द्वारा विज़ुअलाइज़ेशन की अनुमति नहीं है)। यानी विज़ुअलाइज़ेशन केवल n = 8 के लिए है, लेकिन कोड आदर्श रूप से सभी 'एन' के लिए काम करेगा। जीत दर्ज करना सिर्फ शीर्ष मतदान है।

कुछ इसी तरह का प्रश्न: नंद तर्क द्वार का उपयोग करके एक बहुस्तरीय मशीन का निर्माण करें


2
काफी बेहतर। हालांकि "सामान्यीकरण" और "सौंदर्यवादी" उद्देश्य नहीं हैं। सभी प्रश्नों में वस्तुनिष्ठ मानदंड होना चाहिए। यदि आप उन विशेषताओं को लागू करना चाहते हैं, तो लोकप्रियता-प्रतियोगिता का उपयोग करें। यदि आप सबसे छोटा कोड चाहते हैं, तो कोड-गोल्फ का उपयोग करें। यदि आप दो का संयोजन बनाना चाहते हैं, तो कोड-चुनौती का उपयोग करें, लेकिन एक सूत्र निर्दिष्ट करें। उदाहरण के लिए 1.25 * वोट - 0.25 * लंबाई जैसा कि यह सवाल करता है: codegolf.stackexchange.com/questions/23581/eiffel-tower-in-3d/…
लेवल रिवर सेंट

ठीक है, उन छगों को आप पूछते हैं। प्रतिक्रिया के लिए thx
vzn

ओघ, मुझे लगता है कि VHDL या वेरिलॉग को संकलित करने के बाद इसकी सभी अनुकूलन कम से कम जवाब देना चाहिए। मैं इसे बाद में कोशिश करूँगा।
किरिल कुलकोव

1
एक बेहतर जीत का मापदंड गेट-गोल्फ होगा
TheDoctor

@चिकित्सक ??? क्या है gate-golf? वह टैग कोई नहीं है। प्रतिभागियों पर ध्यान दें: कृपया बताएं कि आप किस भाषा / विज़ुअलाइज़ेशन टूल का उपयोग कर रहे हैं। अगर कोई और भी plz टिप्पणी दर्ज करना चाहता है। अन्यथा विजेता टोनाइट स्वीकार करेगा। उत्तरदाताओं के लिए बहुत कुछ यह अब तक "BTE" उम्मीद से बेहतर चला गया!
vzn

जवाबों:


7

संख्या modulo की गणना करने के लिए सर्किट 3

ग्राफ प्रत्येक स्तर पर 3 बूलियन रखता है i। वे इस तथ्य का प्रतिनिधित्व करते हैं कि संख्या के उच्च-क्रम i बिट्स 0, 1, या 2 mod 3 के बराबर हैं। प्रत्येक स्तर पर हम पिछले तीन बिट्स और अगले इनपुट बिट के आधार पर अगले तीन बिट्स की गणना करते हैं।

यहाँ अजगर कोड है जो ग्राफ उत्पन्न करता है। एक अलग मापांक प्राप्त करने के लिए बस N को अलग संख्या में बिट्स, या K बदलने के लिए बदलें। के माध्यम से अजगर कार्यक्रम के उत्पादन में चलाने के लिए डॉट छवि उत्पन्न करने के लिए।

N = 8
K = 3
v = ['0']*(K-1) + ['1']
ops = {}

ops['0'] = ['0']
ops['1'] = ['1']
v = ['0']*(K-1) + ['1']
for i in xrange(N):
  ops['bit%d'%i] = ['bit%d'%i]
  ops['not%d'%i] = ['not','bit%d'%i]
  for j in xrange(K):
    ops['a%d_%d'%(i,j)] = ['and','not%d'%i,v[(2*j)%K]]
    ops['b%d_%d'%(i,j)] = ['and','bit%d'%i,v[(2*j+1)%K]]
    ops['o%d_%d'%(i,j)] = ['or','a%d_%d'%(i,j),'b%d_%d'%(i,j)]
  v = ['o%d_%d'%(i,j) for j in xrange(K)]

for i in xrange(4):
  for n,op in ops.items():
    for j,a in enumerate(op[1:]):
      if ops[a][0]=='and' and ops[a][1]=='0': op[j+1]='0'
      if ops[a][0]=='and' and ops[a][2]=='0': op[j+1]='0'
      if ops[a][0]=='and' and ops[a][1]=='1': op[j+1]=ops[a][2]
      if ops[a][0]=='and' and ops[a][2]=='1': op[j+1]=ops[a][1]
      if ops[a][0]=='or' and ops[a][1]=='0': op[j+1]=ops[a][2]
      if ops[a][0]=='or' and ops[a][2]=='0': op[j+1]=ops[a][1]

for i in xrange(4):
  used = set(['o%d_0'%(N-1)])|set(a for n,op in ops.items() for a in op[1:])
  for n,op in ops.items():
    if n not in used: del ops[n]

print 'digraph {'
for n,op in ops.items():
  if op[0]=='and': print '%s [shape=invhouse]' % n
  if op[0]=='or': print '%s [shape=circle]' % n
  if op[0]=='not': print '%s [shape=invtriangle]' % n
  if op[0].startswith('bit'): print '%s [color=red]' % n
  print '%s [label=%s]' % (n,op[0])
  for a in op[1:]: print '%s -> %s' % (a,n)
print '}'

महान! ग्रेविज़ का भीइस्तेमाल किया है... छोटे वक्रोक्ति, आरेख में अप्रयुक्त एंड्स / ओआरएस हैं। अपने स्थानों को दिखाने के लिए अलग-अलग रंग में इनपुट बिट्स को उजागर करने का सुझाव भी दे सकते हैं
vzn

@vzn: ठीक है, ठीक है।
कीथ रान्डेल

12

गहराई: 7 (लघुगणक), 18x और, 6x OR, 7x XOR, 31 द्वार (रैखिक)

मुझे बेस चार, मोडुलो तीन में अंकों की गणना करें:

7-परत सर्किट एक स्पष्ट रूप से दृश्यमान पदानुक्रमित संरचना के साथ

Logisim में खींचा गया सर्किट

सामान्यीकरण, औपचारिक रूप से (उम्मीद है कि कुछ हद तक पठनीय):

balance (l, h) = {
  is1: l & not h,
  is2: h & not l,
}

add (a, b) = 
  let aa = balance (a.l, a.h)
      bb = balance (b.l, b.h)
  in  { l:(a.is2 & b.is2) | (a.is1 ^ b.is1),
        h:(a.is1 & b.is1) | (a.is2 ^ b.is2)}

pairs [] = []
pairs [a] = [{h:0, l:a}]
pairs [rest.., a, b] = [pairs(rest..).., {h:a, l:b}]

mod3 [p] = p
mod3 [rest.., p1, p2] = [add(p1, p2), rest..]

divisible3 number =
  let {l: l, h: h} = mod3 $ pairs number
  in  l == h

अब अंग्रेजी में:

जबकि संख्या में दो से अधिक बिट्स हैं, दो सबसे कम जोड़े बिट्स लेते हैं और उन्हें 3 modulo योग करते हैं, फिर परिणाम को संख्या के पीछे जोड़ते हैं, फिर वापस आते हैं यदि अंतिम जोड़ी शून्य modulo है 3. यदि कोई विषम है संख्या में बिट्स, शीर्ष पर एक अतिरिक्त शून्य बिट जोड़ें, फिर निरंतर मूल्य प्रसार के साथ पॉलिश करें।

मोर्चे के बजाय पीछे की तरफ जुड़ना यह सुनिश्चित करता है कि अतिरिक्त पेड़ एक लिंक्ड सूची के बजाय एक संतुलित पेड़ है। यह, बदले में, बिट्स की संख्या में लॉगरिदमिक गहराई सुनिश्चित करता है: जोड़ी को रद्द करने के लिए पांच द्वार और तीन स्तर, और अंत में एक अतिरिक्त गेट।

निश्चित रूप से, यदि अनुमानित निकटता वांछित है, तो शीर्ष जोड़ी को सामने की ओर लपेटने के बजाय अगले परत पर बिना पास किए पास करें। हालांकि, इसे लागू किया जाना आसान है (यहां तक ​​कि स्यूडोकोड में भी)। यदि संख्या में बिट्स की संख्या दो की शक्ति है (जैसा कि मार्च 2014 तक किसी भी आधुनिक कंप्यूटर सिस्टम में सच है), तो कोई भी अकेला जोड़े नहीं होगा।

यदि राउटर स्थानीयता को संरक्षित करता है / मार्ग की लंबाई कम करता है, तो उसे सर्किट को पठनीय रखना चाहिए।

यह रूबी कोड किसी भी बिट (यहां तक ​​कि एक) के लिए एक सर्किट आरेख उत्पन्न करेगा। प्रिंट करने के लिए, Logisim में खोलें और छवि के रूप में निर्यात करें:

require "nokogiri"

Port = Struct.new :x, :y, :out
Gate = Struct.new :x, :y, :name, :attrs
Wire = Struct.new :sx, :sy, :tx, :ty

puts "Please choose the number of bits: "
bits = gets.to_i

$ports = (1..bits).map {|x| Port.new 60*x, 40, false};
$wires = [];
$gates = [];

toMerge = $ports.reverse;

def balance a, b
y = [a.y, b.y].max
$wires.push Wire.new(a.x   , a.y , a.x   , y+20),
          Wire.new(a.x   , y+20, a.x   , y+40),
          Wire.new(a.x   , y+20, b.x-20, y+20),
          Wire.new(b.x-20, y+20, b.x-20, y+30),
          Wire.new(b.x   , b.y , b.x   , y+10),
          Wire.new(b.x   , y+10, b.x   , y+40),
          Wire.new(b.x   , y+10, a.x+20, y+10),
          Wire.new(a.x+20, y+10, a.x+20, y+30)
$gates.push Gate.new(a.x+10, y+70, "AND Gate", negate1: true),
          Gate.new(b.x-10, y+70, "AND Gate", negate0: true)
end

def sum (a, b, c, d)
y = [a.y, b.y, c.y, d.y].max
$wires.push Wire.new(a.x   , a.y , a.x   , y+40),
          Wire.new(a.x   , y+40, a.x   , y+50),
          Wire.new(a.x   , y+40, c.x-20, y+40),
          Wire.new(c.x-20, y+40, c.x-20, y+50),
          Wire.new(b.x   , b.y , b.x   , y+30),
          Wire.new(b.x   , y+30, b.x   , y+50),
          Wire.new(b.x   , y+30, d.x-20, y+30),
          Wire.new(d.x-20, y+30, d.x-20, y+50),
          Wire.new(c.x   , c.y , c.x   , y+20),
          Wire.new(c.x   , y+20, c.x   , y+50),
          Wire.new(c.x   , y+20, a.x+20, y+20),
          Wire.new(a.x+20, y+20, a.x+20, y+50),
          Wire.new(d.x   , d.y , d.x   , y+10),
          Wire.new(d.x   , y+10, d.x   , y+50),
          Wire.new(d.x   , y+10, b.x+20, y+10),
          Wire.new(b.x+20, y+10, b.x+20, y+50)
$gates.push Gate.new(a.x+10, y+90, "XOR Gate"),
          Gate.new(b.x+10, y+80, "AND Gate"),
          Gate.new(c.x-10, y+80, "AND Gate"),
          Gate.new(d.x-10, y+90, "XOR Gate")
$wires.push Wire.new(a.x+10, y+90, a.x+10, y+100),
          Wire.new(b.x+10, y+80, b.x+10, y+90 ),
          Wire.new(b.x+10, y+90, a.x+30, y+90 ),
          Wire.new(a.x+30, y+90, a.x+30, y+100),
          Wire.new(d.x-10, y+90, d.x-10, y+100),
          Wire.new(c.x-10, y+80, c.x-10, y+90 ),
          Wire.new(c.x-10, y+90, d.x-30, y+90 ),
          Wire.new(d.x-30, y+90, d.x-30, y+100)
$gates.push Gate.new(d.x-20, y+130, "OR Gate"),
          Gate.new(a.x+20, y+130, "OR Gate")
end

def sum3 (b, c, d)
y = [b.y, c.y, d.y].max
$wires.push Wire.new(b.x   , b.y , b.x   , y+20),
          Wire.new(b.x   , y+20, b.x   , y+30),
          Wire.new(b.x   , y+20, d.x-20, y+20),
          Wire.new(d.x-20, y+20, d.x-20, y+30),
          Wire.new(c.x   , c.y , c.x   , y+60),
          Wire.new(c.x   , y+60, b.x+30, y+60),
          Wire.new(b.x+30, y+60, b.x+30, y+70),
          Wire.new(d.x   , d.y , d.x   , y+10),
          Wire.new(d.x   , y+10, d.x   , y+30),
          Wire.new(d.x   , y+10, b.x+20, y+10),
          Wire.new(b.x+20, y+10, b.x+20, y+30),
          Wire.new(b.x+10, y+60, b.x+10, y+70)
$gates.push Gate.new(b.x+10, y+60 , "AND Gate"),
          Gate.new(d.x-10, y+70 , "XOR Gate"),
          Gate.new(b.x+20, y+100, "OR Gate" )
end

while toMerge.count > 2  
puts "#{toMerge.count} left to merge"
nextToMerge = []
while toMerge.count > 3
 puts "merging four"
 d, c, b, a, *toMerge = toMerge
 balance a, b
 balance c, d
 sum *$gates[-4..-1]
 nextToMerge.push *$gates[-2..-1] 
end
if toMerge.count == 3
 puts "merging three"
 c, b, a, *toMerge = toMerge
 balance b, c
 sum3 a, *$gates[-2..-1]
 nextToMerge.push *$gates[-2..-1]
end
nextToMerge.push *toMerge
toMerge = nextToMerge
puts "layer done"
end

if toMerge.count == 2
b, a = toMerge
x = (a.x + b.x)/2
x -= x % 10
y = [a.y, b.y].max
$wires.push Wire.new(a.x , a.y , a.x , y+10),
          Wire.new(a.x , y+10, x-10, y+10),
          Wire.new(x-10, y+10, x-10, y+20),
          Wire.new(b.x , b.y , b.x , y+10),
          Wire.new(b.x , y+10, x+10, y+10),
          Wire.new(x+10, y+10, x+10, y+20)
$gates.push Gate.new(x, y+70, "XNOR Gate")
toMerge = [$gates[-1]]
end

a = toMerge[0]
$wires.push Wire.new(a.x, a.y, a.x, a.y+10)
$ports.push Port.new(a.x, a.y+10, true)

def xy (x, y)
"(#{x},#{y})"
end
circ = Nokogiri::XML::Builder.new encoding: "UTF-8" do |xml|
xml.project version: "1.0" do
xml.lib name: "0", desc: "#Base"
xml.lib name: "1", desc: "#Wiring"
xml.lib name: "2", desc: "#Gates"
xml.options
xml.mappings
xml.toolbar do
  xml.tool lib:'0', name: "Poke Tool"
  xml.tool lib:'0', name: "Edit Tool"
end #toolbar
xml.main name: "main"
xml.circuit name: "main" do
  $wires.each do |wire|
    xml.wire from: xy(wire.sx, wire.sy), to: xy(wire.tx, wire.ty)
  end #each 
  $gates.each do |gate|
    xml.comp lib: "2", name: gate.name, loc: xy(gate.x, gate.y) do
      xml.a name: "facing", val: "south"
      xml.a name: "size", val: "30"
      xml.a name: "inputs", val: "2"
      if gate.attrs
        gate.attrs.each do |name, value|
          xml.a name: name, val: value 
        end #each
      end #if
    end #comp
  end #each
  $ports.each.with_index do |port, index|
    xml.comp lib: "1", name: "Pin", loc: xy(port.x, port.y) do
      xml.a name: "tristate", val: "false"
      xml.a name: "output",   val: port.out.to_s
      xml.a name: "facing",   val: port.out ? "north" : "south"
      xml.a name: "labelloc", val: port.out ? "south" : "north"
      xml.a name: "label",    val: port.out ? "out" : "B#{index}"
    end #port
  end #each
end #circuit
end #project
end #builder

File.open "divisibility3.circ", ?w do |file|
file << circ.to_xml
end

puts "done"

अंत में, जब 32 बिट के लिए एक आउटपुट बनाने के लिए कहा गया, तो मेरा लेआउट यह उत्पन्न करता है। बेशक, यह बहुत विस्तृत इनपुट के लिए बहुत कॉम्पैक्ट नहीं है:

13-परतदार स्थान के साथ बहुस्तरीयता


अब तक वास्तव में महान और सबसे अच्छा सर्किट / लेआउट दिखता है। कोड किस भाषा में है? अगर आपने किसी को क्या इस्तेमाल किया है? राउटर को एक एल्गोरिथ्म होने का अनुरोध किया गया था, और यह मानना ​​होगा कि एल्गोरिथ्म का उपयोग नहीं किया गया था (हाथ लेआउट) जब तक कि कहा नहीं गया ...
vzn

@vzn को भी लागू किया जाना था? मैं समझ गया कि प्रतिबंध का अर्थ यह है कि हम आरेख को मैन्युअल रूप से आकर्षित कर सकते हैं, लेकिन पठनीयता इस बात पर निर्भर नहीं होनी चाहिए कि आरेख खींचा गया है या नहीं। टिमवेल का सर्किट निश्चित रूप से हाथ से उत्पन्न होता है। छद्म कोड ज्यादातर हास्केल पर आधारित है जिसमें जावास्क्रिप्ट ऑब्जेक्ट जोड़े जाते हैं।
जॉन ड्वोरक

एल्गोरिथ्मिक रूप से बनाए गए विज़ुअलाइज़ेशन का मतलब मूल रूप से एल्गोरिदमिक राउटर से था, लेकिन अब स्वीकार करते हैं कि अस्पष्ट रूप से व्याख्या की जा सकती है। क्रिस्टल स्पष्टता की कमी के लिए खेद है। क्या आप किसी भी स्वचालित लेआउट के बारे में जानते हैं जो आपके हाथ लेआउट के समान परिणाम प्राप्त कर सकता है?
vzn 15

दुर्भाग्यवश नहीं। yEd में बेहतरीन लेआउट हैं लेकिन यह अभिविन्यास को नजरअंदाज करता है। मैं डॉट से कभी परिचित नहीं हुआ और न ही मुझे इसका आउटपुट बिल्कुल अच्छा लगा। मुझे लगता है कि मैं इस छद्मकोड को रूबी (आसान) में अनुवाद कर सकता हूं और अपना स्वयं का विशेष राउटर (बहुत कठिन नहीं, लेकिन जटिल) लिख सकता हूं जो एक लॉजिम सर्किट का निर्यात करेगा (यह सिर्फ एक एक्सएमएल है, और यह भी gzipped नहीं है, इसलिए काफी आसान है)। क्या मुझे (मुझे चाहिए), और क्या मुझे एक अलग उत्तर के रूप में पोस्ट करना चाहिए? इसके अलावा, क्या यह हाथ से डिजाइन के रूप में गिना जाएगा?
जॉन ड्वोरक

सभी अच्छे उत्तर, लेकिन यह अब तक का सबसे सुरुचिपूर्ण लग रहा है
डिजिटल ट्रॉमा

5

2 × 24 नहीं, 2 × 10 + 5 और, 2 × 2 + 5 OR, 2 × 2 NOR

यह पूरी तरह से पैमाने पर नहीं है। जैसे बिल्कुल नहीं। शायद मैं इसे सुधारने की कोशिश करूंगा।

मैंने 30 तक की संख्या के लिए यह परीक्षण किया और यह ठीक काम किया।

वे 2 बड़े सर्किट सक्रिय इनपुट की संख्या गिन रहे हैं:

  • ऊपरी दायां भाग बिट्स की संख्या को समान शक्ति के साथ गिनता है (शून्य से 4)
  • निचले बाएँ एक बिट्स की संख्या एक विषम शक्ति (शून्य से 4) के साथ होती है

यदि उन संख्याओं का अंतर है 0या 3संख्या से विभाज्य है 3। निचले दाहिने सर्किट मूल रूप से प्रत्येक वैध संयोजन नक्शे ( 4,4, 4,1, 3,3, 3,0, 2, 2, 1, 1, 0, 0एक या में)।

बीच में छोटा वृत्त एक एलईडी है जो कि यदि संख्या 3 से विभाज्य है और अन्यथा बंद है।


वाह अच्छा / तेज! ... plz किसी कोड को लिंक करें या उसे इनलाइन करें ... यह भी विस्तार से बताएं कि आपने विज़ुअलाइज़ेशन कैसे किया ...?
vzn

@vzn दृश्यता लॉजिसिम के साथ बनाई गई थी । यह मेरे हाथ से बनाया गया था, लेकिन सामान्य एल्गोरिदम आसानी से एक कार्यक्रम के साथ भी किया जा सकता है। यह उत्तर में आंशिक रूप से समझाया गया है।
तिमुल्ला
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.