Bir cümledeki karakter sayısına göre bazı dinamik programlama yapmaya çalışıyorum. İngilizce alfabenin hangi harfi ekranda en fazla pikseli kaplıyor?
Bir cümledeki karakter sayısına göre bazı dinamik programlama yapmaya çalışıyorum. İngilizce alfabenin hangi harfi ekranda en fazla pikseli kaplıyor?
Yanıtlar:
Hmm, bakalım:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccccccccccccccccccccccc
dddddddddddddddddddddddddddddddddddddddd
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
ffffffffffffffffffffffffffffffffffffffff
gggggggggggggggggggggggggggggggggggggggg
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
llllllllllllllllllllllllllllllllllllllll
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
oooooooooooooooooooooooooooooooooooooooo
pppppppppppppppppppppppppppppppppppppppp
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
ssssssssssssssssssssssssssssssssssssssss
tttttttttttttttttttttttttttttttttttttttt
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
llllllllllllllllllllllllllllllllllllllll
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
W kazanır.
Tabii ki, bu aptalca bir ampirik deney. Hangi mektubun en geniş olduğu konusunda tek bir cevap yoktur. Yazı tipine bağlıdır. Dolayısıyla, ortamınızın cevabını bulmak için benzer bir ampirik deney yapmanız gerekecektir. Ama gerçek şu ki, çoğu yazı tipi aynı kuralları izliyor ve W harfi en geniş olacak.
Bu karakter genişliklerini, bu özel örnek yazı tipi kullanılarak burada yakalanan bir oran biçiminde (W = 100) verin:
https://gist.github.com/imaurer/d330e68e70180c985b380f25e195b90c
Ned Batchelder'in inanılmaz pratik cevabına ek olarak, buraya rakamları merak ederek geldim:
0000000000000000000000000000000000000000
1111111111111111111111111111111111111111
2222222222222222222222222222222222222222
3333333333333333333333333333333333333333
4444444444444444444444444444444444444444
5555555555555555555555555555555555555555
6666666666666666666666666666666666666666
7777777777777777777777777777777777777777
8888888888888888888888888888888888888888
9999999999999999999999999999999999999999
font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
font-size: 15px;
Oh, o Apple, her zaman biraz farklı olmaya çalışıyor ....
font-variant-numeric
: orantılı sayılar hem glifte hem de aralıkta farklı genişliklere izin verirken, tablo sayıları tek aralıklı yazı tiplerine benzer kurallara uymalıdır.
Programlı bir çözüme ne dersiniz?
var capsIndex = 65;
var smallIndex = 97
var div = document.createElement('div');
div.style.float = 'left';
document.body.appendChild(div);
var highestWidth = 0;
var elem;
for(var i = capsIndex; i < capsIndex + 26; i++) {
div.innerText = String.fromCharCode(i);
var computedWidth = window.getComputedStyle(div, null).getPropertyValue("width");
if(highestWidth < parseFloat(computedWidth)) {
highestWidth = parseFloat(computedWidth);
elem = String.fromCharCode(i);
}
}
for(var i = smallIndex; i < smallIndex + 26; i++) {
div.innerText = String.fromCharCode(i);
var computedWidth = window.getComputedStyle(div, null).getPropertyValue("width");
if(highestWidth < parseFloat(computedWidth)) {
highestWidth = parseFloat(computedWidth);
elem = String.fromCharCode(i);
}
}
div.innerHTML = '<b>' + elem + '</b>' + ' won';
Sermaye "M" geleneksel olarak en geniş olanıdır.
Platformunuza bağlı olarak, bir dize veya DrawText () işlevinden bir şekilde width özelliğiyle "getWidth" öğesinin bir yolu olabilir.
Gerekli yazı tipini kullanan ve daha sonra alfabetten geçen ve küçük bir konfigürasyonda saklanan veya sadece başlangıçta A'dan Z'ye bir döngü olarak hesaplamak o kadar basit değil.
Ayrıca yazı tipine bağlıdır. Bunu 1 veya 2 yıl önce Processing ve Helvetica ile yaptım ve pikselleri artırmak için ILJTYFVCPAXUZKHSEDORGNBQMW. Fikir, metni baktığınız yazı tipi ile bir tuval üzerine çizmek, pikselleri saymak, ardından bir HashMap veya Sözlük ile sıralamaktır.
Tabii ki, bu sadece genişlikten ziyade piksel alanını hesapladığından, kullanımınızla doğrudan ilgili olmayabilir. Biraz abartılı da olabilir.
void setup() {
size(30,30);
HashMap hm = new HashMap();
fill(255);
PFont font = loadFont("Helvetica-20.vlw");
textFont(font,20);
textAlign(CENTER);
for (int i=65; i<91; i++) {
background(0);
text(char(i),width/2,height-(textDescent()+textAscent())/2);
loadPixels();
int white=0;
for (int k=0; k<pixels.length; k++) {
white+=red(pixels[k]);
}
hm.put(char(i),white);
}
HashMap sorted = getSortedMap(hm);
String asciiString = new String();
for (Iterator<Map.Entry> i = sorted.entrySet().iterator(); i.hasNext();) {
Map.Entry me = (Map.Entry)i.next();
asciiString += me.getKey();
}
println(asciiString); //the string in ascending pixel order
}
public HashMap getSortedMap(HashMap hmap) {
HashMap map = new LinkedHashMap();
List mapKeys = new ArrayList(hmap.keySet());
List mapValues = new ArrayList(hmap.values());
TreeSet sortedSet = new TreeSet(mapValues);
Object[] sortedArray = sortedSet.toArray();
int size = sortedArray.length;
// a) Ascending sort
for (int i=0; i<size; i++) {
map.put(mapKeys.get(mapValues.indexOf(sortedArray[i])), sortedArray[i]);
}
return map;
}
Chrome - W'da Arial 30 piksel kazanır .
Yazı tiplerinin genişliklerini, xxx tarafından gönderilen çözüm gibi biraz hesaplamak için bir çözüm Alex Michael tarafından bloguna gönderildi (bu da beni yeterince bağladı).
Özet:
Orijinal Mesaj: http://alexmic.net/letter-pixel-count/
Kod:
# -*- coding: utf-8 -*-
from __future__ import division
import os
from collections import defaultdict
from math import sqrt
from PIL import Image, ImageDraw, ImageFont
# Make a lowercase + uppercase alphabet.
alphabet = 'abcdefghijklmnopqrstuvwxyz'
alphabet += ''.join(map(str.upper, alphabet))
def draw_letter(letter, font, save=True):
img = Image.new('RGB', (100, 100), 'white')
draw = ImageDraw.Draw(img)
draw.text((0,0), letter, font=font, fill='#000000')
if save:
img.save("imgs/{}.png".format(letter), 'PNG')
return img
def count_black_pixels(img):
pixels = list(img.getdata())
return len(filter(lambda rgb: sum(rgb) == 0, pixels))
def available_fonts():
fontdir = '/Users/alex/Desktop/English'
for root, dirs, filenames in os.walk(fontdir):
for name in filenames:
path = os.path.join(root, name)
try:
yield ImageFont.truetype(path, 100)
except IOError:
pass
def letter_statistics(counts):
for letter, counts in sorted(counts.iteritems()):
n = len(counts)
mean = sum(counts) / n
sd = sqrt(sum((x - mean) ** 2 for x in counts) / n)
yield letter, mean, sd
def main():
counts = defaultdict(list)
for letter in alphabet:
for font in available_fonts():
img = draw_letter(letter, font, save=False)
count = count_black_pixels(img)
counts[letter].append(count)
for letter, mean, sd in letter_statistics(counts):
print u"{0}: {1:.2f} ± {2:.2f}".format(letter, mean, sd)
if __name__ == '__main__':
main()
Yazı tipine bağlı olacaktır. En rahat olduğunuz bir programlama dilinde, alfabenin her harfini bir kez m boyutlu bir bitmap'e çizdiğiniz küçük bir program oluştururdum. Her pikseli beyazla başlatın. Ardından, her harfi çizdikten sonra beyaz piksel sayısını sayın ve bu sayıyı kaydedin. Bulduğunuz en yüksek sayı aradığınız numaradır.
DÜZENLEME: Aslında hangisinin yalnızca en büyük dikdörtgeni aldığını merak ediyorsanız (ancak pikselden ziyade gerçekten bundan sonra olduğunuza benziyorsa), boyutu bulmak için çeşitli API çağrılarını kullanabilirsiniz, ancak bu programlama diliniz. Örneğin Java'da FontMetrics sınıfını kullanırsınız.
Kabul edilen cevabın W, W'nun WIN olduğunu biliyorum.
Ancak bu durumda W, Genişlik içindir. Kullanılan örnek olay incelemesinde pikselleri incelemek için basit bir genişlik testi kullanılmıştır, ancak toplam piksel sayısı değil yalnızca genişlikti. Kolay bir karşı örnek olarak, kabul edilen cevap O ve Q'nun aynı miktarda piksel aldığını, ancak yalnızca aynı miktarda yer kapladığını varsayar.
Böylece, W en fazla yer kaplar . Ancak, çatladığı tüm pikseller mi?
Bazı ampirik veriler elde edelim. Aşağıdaki B, M ve W'den imgur görüntüleri oluşturdum. Sonra piksel sayılarını analiz ettim (aşağıya bakın), sonuçlar şöyle:
B: 114 piksel
M: 150 piksel
G: 157 piksel
Bunları tuval içine nasıl besledim ve görüntülerden ham piksel verilerini analiz ettim.
var imgs = {
B : "//i.imgur.com/YOuEPOn.png",
M : "//i.imgur.com/Aev3ZKQ.png",
W : "//i.imgur.com/xSUwE7w.png"
};
window.onload = function(){
for(var key in imgs){(function(img,key){
var Out = document.querySelector("#"+key+"Out");
img.crossOrigin = "Anonymous";
img.src=imgs[key];
img.onload = function() {
var canvas = document.querySelector('#'+key);
(canvas.width = img.width,canvas.height = img.height);
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
var data = context.getImageData(0, 0, img.width, img.height).data;
Out.innerHTML = "Total Pixels: " + data.length/4 + "<br>";
var pixelObject = {};
for(var i = 0; i < data.length; i += 4){
var rgba = "rgba("+data[i]+","+data[i+1]+","+data[i+2]+","+data[i+3]+")";
pixelObject[rgba] = pixelObject[rgba] ? pixelObject[rgba]+1 : 1;
}
Out.innerHTML += "Total Whitespace: " + pixelObject["rgba(255,255,255,255)"] + "<br>";
Out.innerHTML += "Total Pixels In "+ key +": " + ((data.length/4)-pixelObject["rgba(255,255,255,255)"]) + "<br>";
};
})(new Image(),key)}
};
<table>
<tr>
<td>
<canvas id="B" width="100%" height="100%"></canvas>
</td>
<td id="BOut">
</td>
</tr>
<tr>
<td>
<canvas id="M" width="100%" height="100%"></canvas>
</td>
<td id="MOut">
</td>
</tr>
<tr>
<td>
<canvas id="W" width="100%" height="100%"></canvas>
</td>
<td id="WOut">
</td>
</tr>
</table>
Sadece tahmin değil , gerçek en uzun glifi bilmek ister misiniz ?
Ve sadece harflerden, rakamlardan ve ortak sembollerden (!, @ Vb.) Bahsetmiyorum. UTF-16'nın tüm 32.834 karakterindeki en uzun glif anlamına gelir.
Bu yüzden, programlı bir çözümü olan @NK tarafından yanıtla başladım ve bazı küçük değişiklikler yaptım:
var capsIndex = 65;
var smallIndex = 97;
var div = document.createElement('div');
div.style.float = 'left';
document.body.appendChild(div);
var highestWidth = 0;
var elem;
for(var i = capsIndex; i < 32834; i++) {
div.innerText = String.fromCharCode(i);
var computedWidth = window.getComputedStyle(div, null).getPropertyValue("width");
if(highestWidth < parseFloat(computedWidth)) {
highestWidth = parseFloat(computedWidth);
elem = String.fromCharCode(i);
}
}
div.innerHTML = '<b>' + elem + '</b>' + ' won';
Bunu çalıştırıp bekledikten (ve bekledikten) sonra çıktıyı verir ௌ won
.
Ve işte burada, UTF-32'deki en uzun karakter! Bazı yazı tiplerinde en uzun glifin is olduğunu, ancak diğer yazı tiplerinin (özellikle tek boşluklu olanların) programın program hesabını aldığı yazı tipinde olduğu gibi karakterlerle çakıştığını unutmayın.