Tugas 8 : SMS Sayang-Sayang
Udah tutup ! Aaaaargh… mana tugas 7 kemaren gw lupa ngumpulin. Yah, sudah lah. Btw, tugas ini mirip ama soal tahu lalu. Gw males nulis lagi. Lihat aja disini ok ! *nunjuk-nunjuk kebawah*
Udah tutup ! Aaaaargh… mana tugas 7 kemaren gw lupa ngumpulin. Yah, sudah lah. Btw, tugas ini mirip ama soal tahu lalu. Gw males nulis lagi. Lihat aja disini ok ! *nunjuk-nunjuk kebawah*
Ya ya ya, emang telat parah. Gw aja baru lihat soalnya sekarang. Mohon dimaklumi lah, akhir2 ini gw sibuk istirahat.
hm, inti soalnya adalah ngitung berapa banyak kata, berapa banyak baris. Sekarang yang kita butuhin, apa definisi kata : ? Jangan buka kamus ! Tapi lihat soalnya, disitu pasti ada definisi kata.
Kata adalah sekumpulan karakter yang pajangnya minimal kita huruf dan dipisah oleh karakter selain alfanumerik. Berarti : “aku.wildan“, “aku’wildan“, dan “aku wildan” masing masing dianggap sebagai dua buah kata. Get My Point ? Ayo Lagi, “dfd34 2323″ ada 2 kata, “wildan.rahman@gmail.com” ada 4 kata. Dst Dst
Sekarang apa itu baris ? Di soal gak ada keterangan lain, yang ada cuman “akhir suatu baris adalah enter” . Artinya, kalau ketemu enter berarti dihitung satu baris. Agak nekad emang, soalnya kadang-kadang gak ada enter di masukan baris terakhir ( langsung EOF ). Tapi ya sudahlah, apes-apes dapet nilai 0, he3..
Sekarang kita ke poin utama, gimana algoritmanya ? Gampang banget :
Yeah, emang cuman segitu. Asumsi tiap baris termasuk baris terakhir selalu diakhiri newline. Gw percayalah ama Pak Julio, he3.. Tapi kalau kalian takut, ubah algoritmya jadi gini :
Yak, semua test case yang kepikir ama gw udah ke handle. Ntahlah kalau ada test case yang lebih liar ( misal inputnya berisi 10 baris, isinya newline doang ). Gw gak tau mesti gimana, he3.. Kenapa harus ribet2 kayak gitu ? Hm.. coba deh dengan tes case gini ( ketikin aja di file text, jangan pencet ENTER ) :
wildan.rahman@gmail.com
Output yang bener : 4 1
wildan.rahman@gmail.co
Ouput yang bener : 3 1
Btw, gimana cara ngecek dia alfanumerik atau bukan ? Pake include ctype, terus gunain fungsi isalnum() . Enak kan ? he3..
Oh iya, gw udah baca soal no 7. Dan kayaknya lumayan susah. Good Luck aja deh. Btw, gw pernah nulis pembahasan soal tahun lalu yang tipe2nya mirip ini, tapi lumayan ribet ( maklum tugas 10 )
http://blogipb.com/index.php/2006/12/14/tugas-10-pilih-model-bintang-iklan/
ya ya ya.. gw tidur dulu yak !
Udah malem, males nulisnya he3.. besok deh
Update ! :
Tugas yang ke 5 ini agak2 “licik” sebenernya. Coba perhatikan :
Udah itu doang sih. Satu lagi yang penting : PAS NGEBACA INPUT JANGAN PAKE IF, TAPI PAKE LOOP. he3
*wajar kawan, semua orang bisa salah*
Soal :
n = 5
*........***……**
***….***
****..****
**********
Ah.. sebenernya tugas ini udah agak lama, tapi gw baru baca sekarang
Sebenernya gw bingung apa yang mau diabahas. Ngasih algoritma sama aja ama ngasih jawaban. he3.. Tapi yah setidaknya, kita belajar nganalisis pola.
Udah dapet pola ? Gabungin Loop dua biji ama seleksi, kelar deh ..
Hm.. Soal tugas ke 3 kayak gini : Misal input nya ( n ) == 5, maka outputnya :
Anak ayam turun 5, mati satu tinggallah 4.
Anak ayam turun 4, mati satu tinggallah 3.
Anak ayam turun 3, mati satu tinggallah 2.
Anak ayam turun 2, mati satu tinggallah 1.
Anak ayam turun 1, mati satu tinggal induknya.
Yep, gak usah pikir panjang, kita langsung susun solusinya :
Yang perlu diperhatikan :
Update : Soal
Karena tugas pertama terlalu gampang dan gak ada yang bisa dibahas, kita langsung loncat ke tugas dua.
Intermezo
Hmm, waktu emang berlalu begitu cepat. Perasaan baru kemarin gw nulis hint tugas algor buat temen gw. Eh, sekarang giliran gw sendiri yang dapet tugas algor, he3..
Ok, kita langsung ajah. Tugas ini sebenernya gampang banget. Coba analisis soalnya, pasti langsung dapet pencerahan. Ini hasil analisis gw :
Sebenernya ada cara lain yang lebih singkat. Cuman butuh 1 variable dan 1 buah seleksi. Silahkan cari sendiri
.
Kesalahan Umum :
spesial buat kali ini gw kasih source jadi ! tapi bahasa pascal yah, he3.. download disini
Fiuh.. udah lama gak online. Sejak pulang ke Bandung baru kali ini gw ngenet lagi. Gak tahu kenapa, waktu hari pertama gw pergi ke Bogor, saat itu juga telepon rumah dinyatakan sudah berfungsi dengan baik. Tapi saat hari pertama gw menginjakan kaki kerumah, saat itu juga telp gw masuk ICU gara-gara kehujanan T_T apes.. Giliran gw ke warnet tadi ampe kudu ngisi bensin 15rebu n kena banjir depan SMP1 Margahayu, rupanya saat itu juga telp rumah gw jalan T_T. hah.. sudah lah.
Btw tadi gw main2 ke GraderAlgor ( site buat ngupulin tugas alpro di IPB ) pake username temen buat ngebaca soal. Iseng-iseng ga buka forum tanya jawab n.. “wah, sakit ni orang” pikir gw..he3.. Ada yang nulis posting kayak gini ( buat yang belum baca atau gak punya akses kesana ajah )

Btw gambarnya gw sensor dikit demi formalitas he3.. Oh ya, gambar itu gw potong biar muat di halaman posting. Halau mau lihat versi full ini linknya
Butuh berapa variabel ? 3 ? 4 ? Kalau sekilas baca soal kayakz qt butuh 4 variabel array untuk nampung tipe warna, jumlah tiap-tiap warna seharusnya, manik2 yang ditemukan, dan jumlah masing2 warna manik2 yang ditemukan. Tapi sebenernya yang kita butuhkan cuman 2 variabel array. 2 variabel itu gw kasih nama char warna[101][20] bwat nyimpen warna manik-manik dan int amount[101] bwat nyimpen jumlah seharusnya dari masing2 manik2. Gimana penggunaanya ? next ->
Pertama adalah membaca input. Untuk membaca input yang awal-awal pastix udah bisa, ya gitu ajah. Karena itu kita bahas pembacaan input selanjutnya saja yaitu manik2 yang ditemukan oleh bu.. bu.. ibu sapa namax ?
scanf(”%s”,color);
while ( strcmp(color,”STOP”) != 0 ) {
for ( i=0; i < n; i++ ) {
if ( strcmp(warna[i],color) == 0 ) {
amount[i]-- ;
}
}
scanf("%s",color);
}
Yang perlu ditekankan disini adalah, input tidak kita tampung dulu tapi langsung diproses saat itu juga. Untuk setiap warna yang ditemukan kurangi nilai amount[i] pada warna yang bersangkutan ( amount[i]– ). Inilah sebenernya inti dari penyelesaian soal ini. jika semua manik-manik warna tertentu ditemukan, maka nilai amount[i] = 0. Dan jika semua amount[i] = 0 maka cukup cetaklah “LENGKAP”.
Buat meriksa lengkap apa kagak gampang kok, untuk tiap2 amount[i] kalau ada nilai yang gak sama dengan 0 maka langsung ubah status ( variabel untuk menyimpan status kelengkapan manik-manik ) menjadi 1 artinya tidak lengkap. Jangan lupa inisialisasi status dengan nilai 0.
Untuk mencetaknya :
if ( status == 1 ) {
sort_it_baby(n) ;
for ( i = 0 ; i < n ; i++ ) {
if ( amount[i] != 0 )
printf(”%s %d\n”,warna[i],amount[i]) ;
}
} else printf(”LENGKAP\n”);
btw tahu kan guna dari fungsi sort_it_baby ? Buat ngurutinnya tinggal tiru cara dari tugas 10. Modif dikit, kelar deh,. Oh ya, gw gak tahu abis kata lengkap ada newline apa kagak. tanya ma dosen aja yah.
Cara yang pertama adalah di sort tiga kali dengan sedikit modifikasi pada saat terjadi perbandingan. Bukankah soal ini diambil dari buku PC ( Programming Challenge ) ? Yup. Terus pasti ada jawabannya kan ? Belum tentu, gak semua soal di buku PC ada jawabannya, tapi kebetulan yang ini ada.
Jika membandingkan pembahasan saya dengan pembahasan yang ada dibuku PC, maka anda akan tahu, beda solusi yang dirancang oleh anak kemarin sore seperti saya dengan solusi yang disusun oleh orang yang sudah mengetik baris code lebih banyak daripada jumlah butir nasi yang pernah ia makan.
Jawaban pada buku PC menggunakan internal sort function dari bahas C ( pada library stdlib.h ) yaitu qsort. Jujur saya gak ngerti dan gagal mengaplikasikannya. Namun ada satu code fungsi menarik yang berhasil saya adopsi sehingga program saya dapat lebih efisien dan lebih singkat daripada program dengan sort 3 kali yang pertama. Solusinya kira -kira kayak gini :
// catatan : swap1 untuk angka dan swap2 untuk string, semua variabel penyimpan data model saya buat global. Saya gunakan 3 buah array tanpa struct
ini fungsi sort yang digunakan :
void sort1(int n)
{
int i,j ;
for (i=0; i < n ; i++ ) {
for ( j = i ; j < n ; j++ ) {
if (compare(i,j) == 1) {
swap1(&tinggi[i],&tinggi[j]) ;
swap1(&berat[i],&berat[j]) ;
swap2(i,j);
}
}
}
}
cukup sekali dan semua data model berhasil diurutkan. Bagaimana bisa ? rahasianya ada fungsi compare yang saya ambil. Seperti ini fungsinya :
int compare( int i, int j )
{
if ( tinggi[i] > tinggi[j] ) return 1 ;
if ( tinggi[i] < tinggi[j] ) return -1 ;
if ( berat[i] > berat[j] ) return 1 ;
if ( berat[i] < berat[j] ) return -1 ;
return strcmp(model[i],model[j]) ;
}
Fungsi compare meniru cara kerja dari fungsi strcmp. hm.. bener2 sip.
Doh.. pas mau nulis tugas ini flashdisk gw ketinggalan. Jadi seadanya aja deh..
Sebenernya tugas ini gak susah-susah amat, tapi karena yang harus di sort nya multiple field, jadinya agak ngerepotin. Soal ini diambil dari bukunya Steven S. Skiena ama Miguel Revilla yang lumayan legendaris berjudul “Programming Challenge: the Programming contest training manual”.
Ada dua struktur data yang bisa digunain, pertama pake struct ( sesuai solusi yang ada di buku itu ), misalkan kita punya variabel berikut : model[].nama, model[].berat, model[].tinggi. Untuk nama jelas yang kita simpen adalah nama, namun untuk berat dan tinggi, kita gak perlu menyimpan nilai tinggi dan berat yang sesungguhnya. Cukup kita simpen selisihnya, yang penting, informasi mengenai urutan tidak hilang.
Kalau gak biasa pake struct, tinggal bikin array 3 biji buat nyimpen masing-masing jenis data. Sekarang kita pake struct ajah.
Misal input berat dan tinggi model kita baca dan disimpan dalam variabel b dan t ( untuk nama langsung aja masukin ke model[i].nama ) maka untuk tiap-tiap pembacaan ( i = model ke-i ) :
model[i].tinggi = abs ( 165 – t ) // abs = absolute value ada di stdlib.h kalau gak salah
jika berat lebih besar dari 65 maka model[i].berat = ( 65 – b) dan jika kecil atau sama maka model[i].berat = -b ;
Mengapa untuk berat seperti itu ? Karena berbeda dengan tinggi, model dicari yang deket ke 65 tapi gak lebih berat. Kalau semua lebih berat baru cari yang paling ringan. Misal ada model dengan tinggi sama mempunyai berat 65, 70, 75, 66, 63. Maka urutannya adalah : 65, 63, 66, 70, 75 dan bukan 65, 66, 63, 70, 75 . Untuk memudahkan pengurutan, maka dalam variabel model[i].berat akan berisi : -65, 10, 15, 1, -63. Saat, mengurutkan berat, kita tinggal mengurutkannya secara menaik.
Lah nanti, data berat aslinya ilang dong ? Tenang aja, yang dicetak kan cuman nama.
Oh ya, saya lupa berat dan tinggi idealnya tu berapa, jadi kalau salah tinggal ubah aja sendiri.
Coz the number of data is not extremely large, i think buble sort is cool enough to solve this problem. Cara yang paling mudah meskipun naif adalah kita membuat 3 buah fungsi sort. Sort pertama kita urutkan model[i].tinggi. Ingat ! saat data ditukar, maka bukan cuman tinggi saja yang ditukar, tapi semua.
sort yang kedua kita urutkan berdasarkan model[i].berat, namun modifikasi sortnya agar data berat yang dibandingkan hanya yang tingginya sama. Jangan lupa juga agar saat proses pertukaran data durutkan semua.
Sort yang terakhir adalah mengurutkan nama. Sama seperti berat, data yang dibandingkan hanya yang berat dan tingginya sama. Bagaimana cara membandingkan nama ? Gunakan fungsi strcmp ( kalau gak salah ada di string.h ).
Terakhir…, tinggal cetak namanya.
Oh ya, untuk fungsi sort, c udah punya di stdlib.h. nama fungsinya qsort, sayang karena gw gak gitu ngerti cara makenya, jadinya gaka akan dibahas, he3.
hm hm hm, gimana cara ngerjainnya ?
Kalau algoritma yang gw pake kayak gini.
pertama siapin variabel array 2 dimensi bertipe char untuk menampung semua keypad nya
char keypad[10][4] = {{’ ‘},{’.'},{’a',’b',’c'},{’d',’e',’f'},{’g',’h',’i'},
{’j',’k',’l'},{’m',’n',’o'},{’p',’q',’r',’s’},{’t',’u',’v'},{’w',’x',’y',’z'}
} ;
nah.. ntar ngeaksesnya pake keypad[tombol][pencet-1] dimana tombol = tombol apa yang dipencet, dan pencet adalah berapa kali tombol itu dipencet. Kenapa pencet-1 ? ntar juga tahu.
Ok, kita mulai ajah, pertama membaca input. Input disimpan dalam baris memanjang, maksimal input 200 karakter. Kita siapin variebel input bertipe char ( char input[201] ) untunk menampungnya. Masukin input dengan gets(input) .Sekarang bagian yang paling penting :
for ( i = 0 ; i < strlen(input) ; i++ ) { // akses input perkarakter
bagaimana cara mengetahui kalau input adalah angka atau bintang ? caranya :
if (input[i] >= ‘0′ && input[i] <= '9') ; jangan lupa '0' dan '9' harus dilingkupi kutip. Mengapa ? input[i] isinya karakter '0' dst bukan angka 0.
nah, sekarang kalau inputnya digit ( bukan bintang ) maka
tombol = input[i] - '0' ; dan..
pencet++ ; ( jangan lupa inisialisasi pencet sebelumnya dengan 0 )
input[i] - '0' akan mengubah karakter angka menjadi angka. Kok bisa ? Jawabannya Adalah code ASCII. Code ASCII '0' adalah 48. '1' adalah 49 dst.. sehingga, untuk mengubah '1' menjadi 1 tinggal kurangi kode ASCII '1' oleh code ASCII '0' ( 49 - 48 = 1 ). dst..
Kalau inputnya bukan bintang. if nya bercabang lagi :
if ( tombol == 1 ) { // kalau tombolnya titik
kata[counter][idx] = keypad[1][0] ; // titik dimasukan
counter++ ; // ganti kata
idx = 0; // kan ganti kata, idx jadi 0 lagi
} else
if ( tombol == 0 ) { // kalau tombolnya spasi
counter++; // ganti kata
idx = 0; // sama kayak yang atas
} else { // kalau huruf
kata[counter][idx] = keypad[tombol][pencet-1] ; // masukan hurufnya
idx++ ; // gak ganti kata lho
}
Jangan lupa untuk merubah pencet kembali jadi 0.
Variabel kata digunakan untuk menyimpan kata ( pasti udah ngerti dari tugas-tugas sebelumnya kan ? ) . Setelah semuanya dipisah pisah, terakhir tinggal mencetak. Untuk mencetak tinggal tiru aja tugas email..
Beberapa yang harus diperhatikan :
1. Ouput baris pertama "bang sms siapa ini bang. bang" panjangnya 29 karakter. Pertanyaannya, setelah kata "bang" yang terakhir, spasi ikut dimasukan atau tidak ? Atau langsung newline ? Kalau dimasukan juga masih muat kan ?
2. Ingat, pemisah kata adalah titik atau spasi.
3. Apakah setelah titik selalu harus ada spasi ? Di Output, setelah bang yang kedua ada titik lalu diikuti dengan spasi. Hal itu karena memang diinputnya setelah titik ada spasi. Bagaimana kalau tidak ada ? ( dan munculnya ditengah-tengah ) Oh ya, jangan samakan titik disini dengan titik di email karena titik di sini bisa digunakan untuk memisahkan kata.